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

Reply via email to