PT-2026-136876
CVE-2026-85036
·
Published
2026-11-04
·
Updated
2026-11-04
Description by
CVSS 3.1
5.7
MediumMetricsAV:A/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
The Bluetooth Classic AVDTP layer defers releasing a session's stream endpoints: bt avdtp l2cap disconnected() in subsys/bluetooth/host/classic/avdtp.c ends with k work submit(&session-> release work), placing the embedded struct k work on the system work queue's pending list. When the same struct bt avdtp object is immediately reused for a new signalling connection, the session memory is re-initialized — a2dp get connection() in subsys/bluetooth/host/classic/a2dp.c memset()s the whole struct bt a2dp, and bt avdtp l2cap accept() / bt avdtp connect() call k work init() on session-> release work — while that work item is still linked into k sys work q.pending. Zeroing a linked sys snode t truncates the list while its tail pointer keeps pointing past the truncation.
The reuse window is deterministic rather than a race. All host RX processing runs on the Bluetooth RX work queue at a cooperative priority (CONFIG BT RX PRIO), while release work is submitted to the lower-priority system work queue, so the release handler cannot run until the RX thread blocks. Because l2cap br recv() processes every signalling command contained in a single L2CAP signalling PDU back-to-back, a peer can send one PDU holding an L2CAP Disconnection Request for the AVDTP signalling channel followed by a Connection Request for PSM 0x0019; the second command reaches the session-reuse path with the release work provably still queued. The peer must already hold an encrypted AVDTP signalling channel, i.e. be a paired/bonded BR/EDR device.
The result is corruption of the global system work queue's pending list: either the queue silently stops executing any work at all (subsequent submissions are appended to a chain the head can no longer reach, and the orphaned items keep their K WORK QUEUED flag forever) or, in the tail variant, the list acquires a self-referencing node that the queue thread spins on. The written values are pointers to other struct k work objects and are not attacker-controlled, so the impact is a device-wide, reboot-required denial of service rather than a controllable write primitive. Only builds with CONFIG BT CLASSIC and CONFIG BT A2DP are affected.
The fix is a two-commit unit, and neither commit closes the path on its own. ec822ceed83b adds a pending-release check to bt avdtp connect() and bt avdtp l2cap accept(), but the A2DP upper layer's a2dp get connection() memset()s the session — including the queued work item's list node and flags — before those checks run, so k work busy get() would observe an already-cleared state. 2bd5ea88c69b closes that by making a2dp get connection() itself skip the reuse and return NULL while the release work is still pending, which both callers already handle by rejecting the connection attempt. Apply both commits together; either one alone leaves the device vulnerable.
Found an issue in the description? Have something to add? Feel free to write us 👾