CVE-2026-99011
High · 7.1CVSS
7.1
EPSS
0.2%
Published
Oct 23, 2026
CISA due date
—
Cloudanix analysis
A recently fixed flaw in the Linux kernel's handling of Bluetooth audio connections could let an attacker crash the system or potentially run code by exploiting a timing issue during connection setup and data transfer.
- Exploitation
- Adjacent Network
- Attacker needs
- User Interaction
- Complexity
- High
- Impact
- Full Compromise
- Component
- OS kernel
- Class
- Memory Corruption
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Use-after-free in Linux kernel Bluetooth SCO subsystem where sco_recv_scodata() can dereference a freed sco_conn object via a weak hcon->sco_data pointer that is cleared without hdev->lock serialization, allowing concurrent kref_get_unless_zero on already-freed memory during hci_rx_work.
Why it matters to the business
Linux systems using Bluetooth audio (SCO) connections face risk of kernel crashes or potential memory corruption leading to denial of service or local privilege escalation, especially on devices handling wireless headsets or hands-free profiles; urgency is low given recent publication and no observed exploitation.
How an attack unfolds
An attacker triggers a race between sco_conn lifetime management and RX path by establishing and tearing down SCO connections while sending data; the missing lock allows sco_recv_scodata to obtain a reference to memory that sco_conn_free has already released under concurrent execution in hci_rx_work.
How to fix it
Apply the upstream fix that gives hcon->sco_data a proper reference, serializes all access under hdev->lock, moves hci_conn ownership to the socket, and ensures sco_conn_del clears the pointer only under lock; rebuild and deploy the patched kernel on all affected systems.
How to confirm the fix worked
Confirm kernel source contains the described locking changes around sco_conn_hold_unless_zero, sco_conn_del, and __sco_chan_add; test by exercising SCO connect/disconnect under load and verify absence of KASAN reports in hci_rx_work.
Typical attack path
- Establish Bluetooth SCO connection via hci_connect_sco
- Trigger concurrent disconnection and data reception paths
- Cause sco_conn_del to clear hcon->sco_data without lock while RX path holds weak reference
- Induce sco_conn_free to release the object
- Execute sco_conn_hold_unless_zero on the freed slab memory from kworker context
How to detect it
Search kernel logs and crash dumps for KASAN slab-use-after-free reports mentioning sco_conn_hold_unless_zero, sco_recv_scodata, or hci_rx_work; look for stack traces involving kworker/u and Bluetooth handle lookup under hdev lock contention.
- BUG: KASAN: slab-use-after-free in sco_conn_hold_unless_zero
- Write of size 4 by task kworker/u
- Workqueue: hci0 hci_rx_work
- sco_recv_scodata+0x13f/0x490
What your security team should do
- Prioritize patching Linux kernels on any system exposing Bluetooth SCO functionality within the next maintenance window
- Monitor for kernel oops or KASAN reports involving sco_conn_hold_unless_zero or hci_rx_work
- Restrict untrusted Bluetooth pairing until patched
- Review downstream dependent packages that ship this kernel for backports
The record
In the Linux kernel, the following vulnerability has been resolved: Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata() sco_recv_scodata() upgrades the weak hcon->sco_data back-pointer to a strong reference under hdev->lock: hci_dev_lock(hdev); hcon = hci_conn_hash_lookup_handle(hdev, handle); ... conn = sco_conn_hold_unless_zero(hcon->sco_data); hci_dev_unlock(hdev); but the pointer is cleared from the other side without that lock. When the last sco_conn reference is dropped, sco_conn_free() ran conn->hcon->sco_data = NULL; with no hdev->lock held, so the RX path could read hcon->sco_data and call kref_get_unless_zero() on an sco_conn that was concurrently freed: BUG: KASAN: slab-use-after-free in sco_conn_hold_unless_zero+0xbe/0x160 Write of size 4 by task kworker/u17:0 Workqueue: hci0 hci_rx_work Call Trace: sco_conn_hold_unless_zero+0xbe/0x160 sco_recv_scodata+0x13f/0x490 hci_rx_work+0x3af/0x730 kref_get_unless_zero() only guards against a zero refcount, not against the backing memory already being freed. Give hcon->sco_data an actual reference on the sco_conn it points to, so the object cannot be freed while the pointer is still installed, and only clear and drop it from sco_conn_del(), which runs under hdev->lock (its callers, sco_connect_cfm() and sco_disconn_cfm(), hold it). The reader in sco_recv_scodata() also takes hdev->lock, so the store and the read are now serialised: the RX path either observes NULL or a reference that is guaranteed to stay valid until it drops its own. sco_conn_add() no longer hands its kref_init() reference to the caller as the connection's only reference; that initial reference is the one owned by hcon->sco_data, and callers get their own via sco_conn_hold(). Because the sco_conn can now outlive the socket (the association keeps it alive until the link goes down), the hci_conn can no longer be dropped from sco_conn_free() without regressing socket close: closing a connected SCO socket must still tear the link down. Move hci_conn ownership to the socket instead: __sco_chan_add() takes an hci_conn reference and it is released from sco_chan_del() and sco_sock_destruct(), exactly once. The sco_conn no longer owns an hci_conn reference, so sco_conn_add() stops consuming one and sco_connect() drops the hci_connect_sco() reference on every path; sco_connect_cfm() no longer needs its hci_conn_hold() dance.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|