[REGRESSION] Bluetooth: btmtk: MT7922 "Failed to send wmt func ctrl (-22)" after 634a4408c0615c ("validate WMT event SKB length before struct access")
Brandon Arnold
brandon.arnold at gmail.com
Sun May 17 16:25:17 PDT 2026
#regzbot introduced: 634a4408c0615c206885e60ea05f489c426f64b6
#regzbot title: MT7922 BT controller never registers (wmt func ctrl
-22) after btmtk WMT SKB-length validation
Hello there.
I wanted to report the below information about a commit that I
confirmed broke my MediaTek MT7922 adapter. The commit is also built
into the main Arch Linux package, so it affected me during a routine
update (see the BBS link in the report below). This adapter is the one
that came with my Framework Laptop 16 system.
Apologies for Claude's verbosity and language but I can confirm I
attended the bisect and revert of the offending diff. Thank you!
Workaround in use: pinned to the Arch Linux pre-7.0.7 kernel.
Thanks,
Brandon Arnold
Commit 634a4408c0615c ("Bluetooth: btmtk: validate WMT event SKB
length before struct access"), backported to 7.0.x stable and shipped
in v7.0.7, breaks Bluetooth on the MediaTek MT7922: the WMT function
control step fails with -EINVAL and the HCI controller never
registers. WiFi on the same chip (mt7921e) is unaffected.
This is NOT a v6.19->v7.0 mainline regression -- mainline v7.0 is
GOOD. The regression is the above commit specifically; it is absent
from v7.0 and v7.0.6 and present in v7.0.7.
Scope / affected versions
-------------------------
- GOOD: mainline v7.0, linux-stable v7.0.6 (commit absent)
- BAD: linux-stable v7.0.7 (commit present)
- Independently reported on Arch (different machine -- Lenovo
IdeaPad, MT7922 USB [0489:e0d8]): BROKEN on linux 7.0.7.arch2-1,
WORKING on 7.0.6.arch1-1, identical symptom.
https://bbs.archlinux.org/viewtopic.php?id=313561
Hardware / firmware (primary reporter)
--------------------------------------
- Framework Laptop 16 (AMD Ryzen AI 300 Series), board FRANMHCP09 A9
- BIOS: INSYDE/Framework 03.04, 2025-11-06
- MT7922, PCI [14c3:0616] subsys [14c3:e616]; BT side USB, driver
btusb/btmtk; WiFi side mt7921e (works)
- linux-firmware 20260410; BT firmware BT_RAM_CODE_MT7922_1_1,
HW/SW Version 0x008a008a, Build Time 20260224103448
- bluez 5.86
Symptom
-------
The firmware download and version handshake still succeed (identical
HW/SW version line before and after), then:
Bluetooth: hci0: HW/SW Version: 0x008a008a, Build Time: 20260224103448
Bluetooth: hci0: Failed to send wmt func ctrl (-22)
No "Device setup in N usecs" follows; BlueZ reports "No default
controller available". hci0 exists in /sys/class/bluetooth and is not
rfkill-blocked. Reproducible deterministically on cold boot,
`modprobe -r btusb; modprobe btusb`, and full USB unbind/rebind. It
fails even with btusb enable_autosuspend=0, so this is distinct from
the known func-ctrl/autosuspend race.
Analysis
--------
634a4408c0615c reworks btmtk_usb_hci_wmt_sync() to validate length
with skb_pull_data() before casting the WMT event:
- wmt_evt = (struct btmtk_hci_wmt_evt *)data->evt_skb->data;
+ wmt_evt = skb_pull_data(data->evt_skb, sizeof(*wmt_evt));
+ if (!wmt_evt) { ... err = -EINVAL; goto err_free_skb; }
...
case BTMTK_WMT_FUNC_CTRL:
+ if (!skb_pull_data(data->evt_skb,
+ sizeof(wmt_evt_funcc->status))) {
+ err = -EINVAL; goto err_free_skb;
+ }
wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
For the FUNC_CTRL response from the MT7922, one of these
skb_pull_data() calls returns NULL and the function returns -EINVAL
(surfaced as "Failed to send wmt func ctrl (-22)"). In effect the
length the driver now requires
(sizeof(struct btmtk_hci_wmt_evt) + sizeof(status)) exceeds what this
controller actually sends for FUNC_CTRL, so a valid handshake is now
rejected. The pre-patch code cast and read the same bytes without the
strict length gate and worked on this hardware.
Empirical confirmation (mainline, no distro patches)
----------------------------------------------------
Built faithfully from the running Arch config (only LOCALVERSION
added); no out-of-tree changes.
- mainline v7.0 : GOOD (commit absent)
- linux-stable v7.0.7 : BAD (kernel 7.0.7-bisect; WMT func ctrl -22
count = 1; hci0 device setup never completes; bluetoothctl shows 0
controllers)
- v7.0.7 + revert of
70d37a8b9229 (the 7.0.7
backport of 634a4408c0615c): GOOD (kernel
7.0.7-bisect-00001-ge33bfb5d7480; WMT func ctrl -22 count = 0; hci0
device setup OK; bluetoothctl shows 1 controller)
The reverted tree's drivers/bluetooth/btmtk.c is byte-identical to
v7.0.6 (git diff v7.0.6 -- drivers/bluetooth/btmtk.c is empty), so the
v7.0.7-vs-revert pair isolates exactly this one commit.
Reproduction
------------
1. Boot a kernel >= v7.0.7-equivalent on MT7922 hardware.
2. `bluetoothctl list` -> no controller.
3. `journalctl -k -b | grep 'wmt func ctrl'` -> -22.
4. Revert 634a4408c0615c (or boot v7.0.6) -> controller registers.
A straight revert restores operation and is offered as the candidate
fix; alternatively the length checks should be relaxed to match the
MT7922's actual FUNC_CTRL WMT event length. I can test patches, or
provide full bad/good kernel logs, btmon/hci traces, and the exact
short SKB length on request.
More information about the Linux-mediatek
mailing list