CVE-2026-90091: Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: L2CAP: fix race l2capsockcleanuplisten() vs. putchan
For L2CAP sockets without owning sk->sksocket, reading l2cappi(sk)->chan may race against concurrent l2capsockkill() -> l2capsockputchan(). This excludes simultaneous protoops callbacks, but access in l2capsockcleanuplisten() has unsafe lockless read.
[Task 1] [Task 2 (hdev->workqueue)] l2capsockrelease(parent) l2capdisconncfm l2capsockcleanuplisten l2capconndel btacceptdequeue l2capchandel locksock(sk) l2capsockteardowncb btacceptunlink btsk(sk)->parent = NULL releasesock(sk) ----------------> locksock(sk) parent = / NULL / locksock(sk) <--------------------- releasesock(sk) socksetflag(sk, SOCKZAPPED) l2capsockclosecb l2capsockkill(sk) l2capsockputchan chan = READ l2cappi(sk)->chan l2cappi(sk)->chan = NULL l2capchanholdunlesszero l2capputchan(chan) krefgetunlesszero(&chan->ref)
Task 1 may observe NULL which causes null-ptr-deref.
Fix the race by taking locksock() in l2capsockkill() to synchronize with l2capsockcleanuplisten(). holdunlesszero() is not needed here, l2cappi(sk)->chan owns reference if it is non-NULL.
Clarify code comments vs. locking.
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
If you cannot immediately apply the kernel fix, mitigate the null-ptr-deref risk by limiting exposure of Bluetooth L2CAP functionality (e.g., disable Bluetooth or restrict Bluetooth usage at the host level).
Event History
Frequently Asked Questions
What conditions are needed to trigger this issue?
The race requires concurrent L2CAP socket cleanup and channel teardown activity. Specifically, l2cap_sock_cleanup_listen() can read the channel pointer while l2cap_sock_kill() concurrently clears it through l2cap_sock_put_chan().
What is the impact if the race occurs?
The cleanup path can observe a NULL channel pointer, leading to a null-pointer dereference in the kernel.
Does the fix rely on preventing simultaneous protocol-operation callbacks?
No. The issue concerns an unsafe lockless access in l2cap_sock_cleanup_listen(), even though simultaneous proto_ops callbacks are excluded. The fix synchronizes the paths by taking lock_sock() in l2cap_sock_kill().