CVE-2026-98455: Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMMCONNINFO
The RFCOMMCONNINFO getsockopt handler accepts a socket that is not connected as long as deferred setup is enabled:
if (sk->skstate != BTCONNECTED && !rfcommpi(sk)->dlc->defersetup) { err = -ENOTCONN; break; } l2capsk = rfcommpi(sk)->dlc->session->sock->sk;
dlc->defersetup is set in rfcommsockinit() when rfcommconnectind() creates a child socket for an incoming connection on a listening socket that has BTDEFERSETUP enabled. It is never cleared afterwards. The session, however, can go away underneath it.
rfcommrecvdisc() forces the dlc state before tearing it down:
d->state = BTCLOSED; rfcommdlcclose(d, err);
The RFCOMMDEFERSETUP early return in rfcommdlcclose() only covers BTCONNECT, BTCONFIG, BTOPEN and BTCONNECT2, so with the state already BTCLOSED that switch does not match and the function falls through to rfcommdlcunlink(), which sets d->session = NULL, while d->defersetup stays 1.
A getsockopt(SOLRFCOMM, RFCOMMCONNINFO) on the accepted socket after that point therefore skips the -ENOTCONN path -- sk->skstate is BTCLOSED, but dlc->defersetup is still set -- and dereferences the NULL session. No race is needed: once the DISC has been processed, the dereference is unconditional.
Reproduced on a KASAN kernel under QEMU with a BR/EDR peer emulated over /dev/vhci: the peer brings up an ACL link, opens L2CAP on the RFCOMM PSM, starts a session and sends SABM for a channel bound with BTDEFERSETUP, and sends DISC for that dlci after the socket has been accepted. getsockopt(SOLRFCOMM, RFCOMMCONNINFO) on the accepted socket then hits:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017] CPU: 1 UID: 0 PID: 150 Comm: init Tainted: G B 7.3.0-rc3-g5dd1818b15d9 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) RIP: 0010:rfcommsockgetsockopt+0x529/0x780 Call Trace: <TASK> dosockgetsockopt+0x3ad/0x7d0 sysgetsockopt+0x10e/0x1b0 x64sysgetsockopt+0xc2/0x160 dosyscall64+0xda/0x4b0 entrySYSCALL64afterhwframe+0x77/0x7f </TASK>
0x10 is the offset of sock in struct rfcommsession; rfcommsockgetsockoptold() is inlined into rfcommsockgetsockopt().
Commit 43a556b2fd43 ("Bluetooth: RFCOMM: take rfcommmutex for the deferred setup accept") fixed the same "a remote DISC clears the session while deferred setup is still flagged" problem in rfcommdlcaccept(); this is the remaining instance of it, in the getsockopt path.
Deferred setup only leaves a socket usable here once it has reached BTCONNECT2, so restrict the exception to that state and check that a session is actually present before following it.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
In the RFCOMM_CONNINFO getsockopt handler, permit the deferred-setup exception only when the DLC is in state BT_CONNECT2 and verify that BT_DEFER_SETUP is enabled before dereferencing dlc->session; otherwise return -ENOTCONN.