CVE-2026-90092: Bluetooth: L2CAP: reject accept queue add unless BT_LISTEN
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: L2CAP: reject accept queue add unless BTLISTEN
New sk should not be added to parent socket accept queue after last l2capsockcleanuplisten() has run in l2capsockteardowncb() and state set to BTCLOSED, as that can result to UAF on dereferencing the dangling parent reference.
l2capsocknewconnectioncb() may race with parent l2capchan teardown, due to chan->state accessed without consistent locking:
[Task 1] [Task 2] l2capsockrelease(parent) l2capconnect l2capsockshutdown pchan = l2capglobalchanbypsm l2capchanlock(pchan) l2capchanclose l2capsockteardowncb pchan->state = BTCLOSED l2capchanunlock(pchan) ------> l2capchanlock(pchan) l2capnewconnection l2capsocknewconnectioncb l2capchanlock(pchan) <-------- l2capchanunlock(pchan) l2capsockkill(parent) / btsk(sk)->parent dangling /
Fix by adding check for skstate == BTLISTEN after acquiring sk lock in l2capsocknewconnectioncb(). Add locksock() around skstate writes where missing, to avoid data races.
Although the data races on pchan->state should be fixed too, this defensive skstate check probably makes sense in any case.
Affected Software
Event History
Frequently Asked Questions
What conditions are required to trigger this issue?
A race must occur between teardown of an L2CAP parent socket that was listening and creation of a new L2CAP connection. The new connection callback can otherwise add a child socket to the parent accept queue after the parent has been closed and its parent reference has become dangling.
Which Linux systems are exposed?
Systems using the Linux kernel Bluetooth L2CAP socket handling are relevant. The provided information does not identify affected kernel versions, configurations, or whether Bluetooth must be enabled and in active use.
How does the fix prevent the use-after-free?
The fix checks that the socket state is still BT_LISTEN after acquiring the socket lock before adding a new socket to the accept queue. It also adds socket locking around previously unprotected socket-state writes to prevent data races.