LP: #2165873 - Confirmed kernel regression in 6.8.0-139: incomplete
btmtk stable backport leaves data->intf NULL
Root Cause Summary
This is a real regression in 6.8.0-139.139~22.04.1, caused by an incomplete
stable backport of the MediaTek btmtk refactor series. It is not a firmware or
BIOS issue, and it is not specific to this machine.
6.8.0-139 pulled in five commits as stable dependencies of the target fix
dd1dda6b8d6e ("Bluetooth: btmtk: fix urb->setup_packet leak in error paths",
BugLink LP #2160250):
- 00f993fdec06 Bluetooth: btmtk: add the function to get the fw name
- 4c0c28f2bbec Bluetooth: btusb: mediatek: refactor btusb_mtk_reset
- d3e6236053958 Bluetooth: btmtk: rename btmediatek_data
- d019930b0049 Bluetooth: btmtk: move btusb_mtk_hci_wmt_sync to btmtk.c
- dd1dda6b8d6e Bluetooth: btmtk: fix urb->setup_packet leak in error paths
d019930b0049 moved btusb_mtk_hci_wmt_sync() from btusb.c into btmtk.c as
btmtk_usb_hci_wmt_sync(). The important semantic change is where the private
data comes from:
6.8.0-138 and earlier: struct btusb_data *data = hci_get_drvdata(hdev);
-> data->intf is set in btusb_probe(), so it is always valid.
6.8.0-139: struct btmtk_data *data = hci_get_priv(hdev);
-> a different struct, with its own new udev/intf/ctrl_anchor members.
Upstream, those new btmtk_data members are populated by the NEXT commit in the
series, 5c5e8c52e3ca ("Bluetooth: btmtk: move btusb_mtk_[setup, shutdown] to
btmtk.c"), which adds to btusb_mtk_setup():
btmtk_data->intf = data->intf;
btmtk_data->udev = data->udev;
btmtk_data->ctrl_anchor = &data->ctrl_anchor;
5c5e8c52e3ca is NOT present in 6.8.0-139. In the shipped tree the only
btmtk_data fields ever assigned in btusb.c are dev_id and reset_sync, so intf,
udev and ctrl_anchor remain NULL from the zeroed hdev private area, while
btmtk.c dereferences all three.
Result: btusb_mtk_setup() -> btmtk_setup_firmware_79xx() ->
btmtk_usb_hci_wmt_sync() calls usb_autopm_get_interface(NULL) on the first WMT
command, which faults in __pm_runtime_resume(). The oops occurs on the hci0
workqueue while hdev->req_lock is held, the kworker dies with IRQs disabled,
and hci0 is left stuck in DOWN INIT with an all-zero BD address.
Key Evidence
- Call chain from dmesg-6.8.0-139.txt:
BUG: kernel NULL pointer dereference, address: 0000000000000219
Oops: 0000 [#1] PREEMPT SMP NOPTI
Workqueue: hci0 hci_power_on [bluetooth]
RIP: 0010:__pm_runtime_resume+0x1b/0x80
usb_autopm_get_interface+0x1d/0x60
btmtk_usb_hci_wmt_sync+0xb9/0x340 [btmtk]
btmtk_setup_firmware_79xx+0x1c7/0x360 [btmtk]
btusb_mtk_setup+0x2d6/0x610 [btusb]
hci_dev_setup_sync+0x6c/0x440 [bluetooth]
hci_dev_open_sync+0x8b/0x350 [bluetooth]
hci_power_on+0x50/0x210 [bluetooth]
note: kworker/u33:1[340] exited with irqs disabled
- Register-level proof the NULL pointer is data->intf:
RDI: 0000000000000050 CR2: 0000000000000219
Code: ... 48 89 fb 75 09 <f6> 87 c9 01 00 00 04 ...
The faulting instruction is testb $0x4, 0x1c9(%rdi). 0x50 + 0x1c9 = 0x219,
which matches CR2 exactly, and RDI = 0x50 is
offsetof(struct usb_interface, dev). So usb_autopm_get_interface() was
called with intf == NULL. This is a plain NULL field, not a freed or raced
pointer, which rules out a use-after-free.
- The crash happens after "hci0: HW/SW Version: 0x008a008a" is read
successfully. btusb_mtk_id_get() still uses the old btusb path, so ID reads
work; the first WMT command through the new btmtk path is what dies.
- 6.8.0-138 on the same hardware and same firmware completes cleanly:
Bluetooth: hci0: Device setup in 138448 usecs
Bluetooth: hci0: AOSP extensions version v1.00
Bluetooth: MGMT ver 1.22
- Device enumerates normally before BT init: usb 1-3, ID 0e8d:223c MediaTek
Inc. Wireless_Device. RfKill.txt shows hci0 neither soft nor hard blocked,
and btmtk is loaded and bound to btusb. The PCIe WiFi side (mt7921e) is
unaffected and comes up as wlp4s0, consistent with a btmtk-USB-only defect.
- Reporter confirms linux-firmware (20220329.git681281e4-0ubuntu3.42) and
bluez (5.64-0ubuntu1.4) are identical on both kernels.
Scope
The missing initialization is in the common btusb_mtk_setup() path and is not
guarded by any device ID. Affected dev_id values in the 6.8.0-139 switch are
0x7663, 0x7668, 0x7922, 0x7961 and 0x7925, so every MT76xx/MT79xx USB
Bluetooth adapter is expected to fail on this kernel, not just this CID. The
3/3 fail rate reflects a structural defect rather than a timing-dependent race.
Note that data->udev and data->ctrl_anchor are equally NULL. Even if the intf
dereference were avoided, usb_mark_last_busy(NULL), usb_rcvctrlpipe(NULL, 0)
and usb_anchor_urb(urb, NULL) would fault next, so a fix touching only intf is
not sufficient.
Recommended Actions
1. Treat this as a release-blocking regression for 6.8.0-139.139~22.04.1. It
breaks all MediaTek USB Bluetooth controllers, not only this platform.
2. Preferred: revert the five-commit btmtk series from 6.8.0-139. The target
fix dd1dda6b8d6e only addresses a urb->setup_packet leak on error paths,
which is far less severe than complete loss of Bluetooth.
3. Alternative: respin with the missing field initialization, cherry-picking
just the relevant hunk of upstream 5c5e8c52e3ca into btusb_mtk_setup() in
drivers/bluetooth/btusb.c, alongside the existing dev_id/reset_sync
assignments:
mediatek->intf = data->intf;
mediatek->udev = data->udev;
mediatek->ctrl_anchor = &data->ctrl_anchor;
All three source fields already exist in struct btusb_data in 6.8.0-139, so
this builds as-is. drv_name is not required because the 6.8.0-139 btmtk.c
does not reference it. Backporting the whole of 5c5e8c52e3ca (roughly 450
lines moved) into an SRU is not advisable; that scale of change is what
produced this regression.
4. Notify the SRU/stable team and the LP #2160250 owner that dd1dda6b8d6e was
applied without its prerequisite 5c5e8c52e3ca, and audit other Ubuntu
kernels currently in -proposed that took dd1dda6b8d6e for the same missing
prerequisite.
5. On the respun kernel, re-run bluetooth/detect-output and
bluetooth4/beacon_eddystone_url_hc0, confirm hciconfig -a reports a
non-zero BD address, and confirm no oops in dmesg. Testing a second
MediaTek part (MT7921 or MT7925) would confirm the fix is generic.
Related Past Issues
- LP: #2164844 (https://bugs.launchpad.net/bugs/2164844): "Bluetooth (MediaTek
MT7922) fails with 'wmt command timed out' on kernel 7.0.0-30-generic, works
on 7.0.0-29-generic". Same vendor and part class, same regression shape
(works on N-1, breaks on N, linux-firmware unchanged) and same WMT handshake
path, but a different visible symptom (-110 timeout loop with repeated hci
device creation rather than a NULL oops). Possibly a separate defect in the
same btmtk refactor area; worth checking whether 7.0.0-30 carries a related
partial btmtk backport.
- LP: #2092473 (https://bugs.launchpad.net/bugs/2092473): "[SRU] Fix system
hang issue caused by the btmtk driver" (oem-priority, verification-done on
noble linux-oem-6.11). Earlier precedent of btmtk driver changes causing
severe regressions in Ubuntu kernels.
- LP: #2152231 (https://bugs.launchpad.net/bugs/2152231): "Bluetooth audio
stuttering regression with MediaTek MT7921 on kernel 6.17.0-23". Same driver
family, different symptom; noted only as MediaTek BT regression context.
- LP: #2160250 (https://bugs.launchpad.net/bugs/2160250): the BugLink carried
by all five commits in this series, i.e. the SRU that introduced this
regression.
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2165873
Title:
Bluetooth fails to initialize due to a kernel NULL pointer error
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux-hwe-6.8/+bug/2165873/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs