CVE-2026-80683: Bluetooth: SCO: give the socket its own sco_conn reference
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: SCO: give the socket its own scoconn reference
scoconndel() drops a reference it does not own. It takes one transient reference via scoconnholdunlesszero() and releases it with the scoconnput() that follows scosockhold(); the additional put in the !sk branch releases a second one:
conn = scoconnholdunlesszero(conn); ... sk = scosockhold(conn); scoconnunlock(conn); scoconnput(conn);
if (!sk) { scoconnput(conn); return; }
When close() races the controller's Disconnection Complete, scochandel() clears conn->sk and drops the socket's reference while scoconndel() is running. scoconndel() then sees sk == NULL, its own put drops the count to zero and frees the conn, and the second put writes to the freed kref:
BUG: KASAN: slab-use-after-free in scoconnput.part.0+0x1a/0x190 Write of size 4 at addr ffff8881099dec74 by task kworker/u17:3/413 Workqueue: hci1 hcirxwork Call Trace: scoconnput.part.0+0x1a/0x190 hcidisconncompleteevt+0x1ee/0x3e0 hcieventpacket+0x54a/0x650 hcirxwork+0x321/0x3d0 Allocated by task 413: scoconnadd+0x72/0x1a0 scoconnectcfm+0x88/0x670 Freed by task 413: scoconndel.isra.0+0x3f/0xf0 hcidisconncompleteevt+0x1ee/0x3e0 refcountt: underflow; use-after-free.
The root cause is that the socket stores the connection without holding a reference of its own. scochanadd() does:
scopi(sk)->conn = conn;
so the socket borrows whatever reference its caller happened to hold, and the callers paper over that with ad-hoc holds and puts. Give the socket a counted reference instead: scochanadd() takes one and it is released together with the channel (scochandel()) and in scosockdestruct(). With the socket holding its own reference, scoconndel() no longer needs the extra put and the redundant hold in scoconnready() goes away.
Making the socket own its reference means the connection is now actually freed on the error paths of scoconnect() where it used to leak, which in turn runs scoconnfree() and its hciconndrop(conn->hcon). To keep the hciconn accounting balanced, make that ownership explicit as well: scoconnadd() consumes one hciconn reference and the scoconn owns it for its lifetime. scoconnect() hands over the reference returned by hciconnectsco() and no longer drops it on the error paths; scoconnectcfm(), which is not given a reference, takes one with hciconnhold() before handing it to scoconnadd() (and drops it again if the allocation fails); and the explicit hciconnhold() in scoconnready() is removed. Every reference then has a single, clear owner.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
ubuntu/linux-hwe-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-42.42~24.04.1 - Upgrade
Upgrade
ubuntu/linux-riscv-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-42.42.1~24.04.1 - Upgrade
Upgrade
ubuntu/linuxto a version that resolves this vulnerability.Fixed in 7.0.0-42.42 - Upgrade
Upgrade
ubuntu/linux-awsto a version that resolves this vulnerability.Fixed in 7.0.0-1016.17 - Upgrade
Upgrade
ubuntu/linux-gcpto a version that resolves this vulnerability.Fixed in 7.0.0-1016.18 - Upgrade
Upgrade
ubuntu/linux-ibmto a version that resolves this vulnerability.Fixed in 7.0.0-1017.17 - Upgrade
Upgrade
ubuntu/linux-oem-7.0to a version that resolves this vulnerability.Fixed in 7.0.0-1017.17 - Upgrade
Upgrade
ubuntu/linux-oracleto a version that resolves this vulnerability.Fixed in 7.0.0-1015.16 - Upgrade
Upgrade
ubuntu/linux-riscvto a version that resolves this vulnerability.Fixed in 7.0.0-42.42.1
Event History
Frequently Asked Questions
Which systems are exposed to this race condition?
Systems using Linux kernel Bluetooth SCO sockets are exposed when socket close can race with a controller Disconnection Complete event. The race involves SCO connection teardown and does not require the connection to remain associated with a socket when the event is handled.
How could an affected system indicate that this issue has occurred?
A KASAN-enabled kernel may report a slab use-after-free in sco_conn_put.part.0 during hci_disconn_complete_evt processing, typically from the hci_rx_work workqueue. The reported fault is a write to freed kref memory after the SCO connection reference count reaches zero.