PT-2026-82983 · Linux · Linux
CVE-2026-80683
·
Published
2026-08-28
·
Updated
2026-08-28
CVSS v3.1
8.8
High
| Vector | AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: SCO: give the socket its own sco conn reference
sco conn del() drops a reference it does not own. It takes one transient
reference via sco conn hold unless zero() and releases it with the
sco conn put() that follows sco sock hold(); the additional put in the
!sk branch releases a second one:
conn = sco conn hold unless zero(conn);
...
sk = sco sock hold(conn);
sco conn unlock(conn);
sco conn put(conn);
if (!sk) {
sco conn put(conn);
return;
}
When close() races the controller's Disconnection Complete, sco chan del()
clears conn->sk and drops the socket's reference while sco conn del() is
running. sco conn del() 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 sco conn put.part.0+0x1a/0x190
Write of size 4 at addr ffff8881099dec74 by task kworker/u17:3/413
Workqueue: hci1 hci rx work
Call Trace:
sco conn put.part.0+0x1a/0x190
hci disconn complete evt+0x1ee/0x3e0
hci event packet+0x54a/0x650
hci rx work+0x321/0x3d0
Allocated by task 413:
sco conn add+0x72/0x1a0
sco connect cfm+0x88/0x670
Freed by task 413:
sco conn del.isra.0+0x3f/0xf0
hci disconn complete evt+0x1ee/0x3e0
refcount t: underflow; use-after-free.
The root cause is that the socket stores the connection without holding a
reference of its own. sco chan add() does:
sco pi(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: sco chan add() takes one and it is released
together with the channel (sco chan del()) and in sco sock destruct().
With the socket holding its own reference, sco conn del() no longer needs
the extra put and the redundant hold in sco conn ready() goes away.
Making the socket own its reference means the connection is now actually
freed on the error paths of sco connect() where it used to leak, which in
turn runs sco conn free() and its hci conn drop(conn->hcon). To keep the
hci conn accounting balanced, make that ownership explicit as well:
sco conn add() consumes one hci conn reference and the sco conn owns it for
its lifetime. sco connect() hands over the reference returned by
hci connect sco() and no longer drops it on the error paths;
sco connect cfm(), which is not given a reference, takes one with
hci conn hold() before handing it to sco conn add() (and drops it again if
the allocation fails); and the explicit hci conn hold() in sco conn ready()
is removed. Every reference then has a single, clear owner.
Fix
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Linux