CVE-2026-80683: Bluetooth: SCO: give the socket its own sco_conn reference

Published Aug 28, 2026
·
Updated

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

1 affected component
Linux Kernel

Event History

Aug 28, 2026
CVE Published
via MITRE·06:52 AM
Data Sourced
via MITRE·06:52 AM
Description

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203