CVE-2026-99011 (GCVE-0-2026-99011)
Vulnerability from cvelistv5 – Published: 2026-10-23 12:20 – Updated: 2026-10-24 14:09
VLAI
EPSS
VEX
Title
Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata()
Summary
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.
Severity
7.1 (High)
Assigner
References
Impacted products
2 products
| Vendor | Product | Version | CPE status | |
|---|---|---|---|---|
| Linux | Linux |
Affected:
e6720779ae612a14ac4ba7fe4fd5b27d900d932c , < b108ea7ebba147465f4158d8133f0e8f013762ed
(git)
Affected: e6720779ae612a14ac4ba7fe4fd5b27d900d932c , < 8a98d58f6cfe70d51138cd9ce894e72671d95f8a (git) Affected: e6720779ae612a14ac4ba7fe4fd5b27d900d932c , < 816fb1590a4c8cf8d05cd076057616be02e276f0 (git) |
guessed | |
| Linux | Linux |
Affected:
6.13
Unaffected: 0 , < 6.13 (semver) Unaffected: 6.18.57 , ≤ 6.18.* (semver) Unaffected: 7.2.11 , ≤ 7.2.* (semver) Unaffected: 7.3 , ≤ * (original_commit_for_fix) |
guessed |
{
"containers": {
"cna": {
"affected": [
{
"defaultStatus": "unaffected",
"product": "Linux",
"programFiles": [
"net/bluetooth/sco.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"lessThan": "b108ea7ebba147465f4158d8133f0e8f013762ed",
"status": "affected",
"version": "e6720779ae612a14ac4ba7fe4fd5b27d900d932c",
"versionType": "git"
},
{
"lessThan": "8a98d58f6cfe70d51138cd9ce894e72671d95f8a",
"status": "affected",
"version": "e6720779ae612a14ac4ba7fe4fd5b27d900d932c",
"versionType": "git"
},
{
"lessThan": "816fb1590a4c8cf8d05cd076057616be02e276f0",
"status": "affected",
"version": "e6720779ae612a14ac4ba7fe4fd5b27d900d932c",
"versionType": "git"
}
]
},
{
"defaultStatus": "affected",
"product": "Linux",
"programFiles": [
"net/bluetooth/sco.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"status": "affected",
"version": "6.13"
},
{
"lessThan": "6.13",
"status": "unaffected",
"version": "0",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.18.*",
"status": "unaffected",
"version": "6.18.57",
"versionType": "semver"
},
{
"lessThanOrEqual": "7.2.*",
"status": "unaffected",
"version": "7.2.11",
"versionType": "semver"
},
{
"lessThanOrEqual": "*",
"status": "unaffected",
"version": "7.3",
"versionType": "original_commit_for_fix"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "6.18.57",
"versionStartIncluding": "6.13",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "7.2.11",
"versionStartIncluding": "6.13",
"vulnerable": true
},
{
"criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
"versionEndExcluding": "7.3",
"versionStartIncluding": "6.13",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
]
}
],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nBluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata()\n\nsco_recv_scodata() upgrades the weak hcon-\u003esco_data back-pointer to a\nstrong reference under hdev-\u003elock:\n\n hci_dev_lock(hdev);\n hcon = hci_conn_hash_lookup_handle(hdev, handle);\n ...\n conn = sco_conn_hold_unless_zero(hcon-\u003esco_data);\n hci_dev_unlock(hdev);\n\nbut the pointer is cleared from the other side without that lock. When\nthe last sco_conn reference is dropped, sco_conn_free() ran\n\n conn-\u003ehcon-\u003esco_data = NULL;\n\nwith no hdev-\u003elock held, so the RX path could read hcon-\u003esco_data and\ncall kref_get_unless_zero() on an sco_conn that was concurrently freed:\n\n BUG: KASAN: slab-use-after-free in sco_conn_hold_unless_zero+0xbe/0x160\n Write of size 4 by task kworker/u17:0\n Workqueue: hci0 hci_rx_work\n Call Trace:\n sco_conn_hold_unless_zero+0xbe/0x160\n sco_recv_scodata+0x13f/0x490\n hci_rx_work+0x3af/0x730\n\nkref_get_unless_zero() only guards against a zero refcount, not against\nthe backing memory already being freed.\n\nGive hcon-\u003esco_data an actual reference on the sco_conn it points to, so\nthe object cannot be freed while the pointer is still installed, and only\nclear and drop it from sco_conn_del(), which runs under hdev-\u003elock (its\ncallers, sco_connect_cfm() and sco_disconn_cfm(), hold it). The reader in\nsco_recv_scodata() also takes hdev-\u003elock, so the store and the read are\nnow serialised: the RX path either observes NULL or a reference that is\nguaranteed to stay valid until it drops its own.\n\nsco_conn_add() no longer hands its kref_init() reference to the caller as\nthe connection\u0027s only reference; that initial reference is the one owned\nby hcon-\u003esco_data, and callers get their own via sco_conn_hold().\n\nBecause the sco_conn can now outlive the socket (the association keeps it\nalive until the link goes down), the hci_conn can no longer be dropped\nfrom sco_conn_free() without regressing socket close: closing a connected\nSCO socket must still tear the link down. Move hci_conn ownership to the\nsocket instead: __sco_chan_add() takes an hci_conn reference and it is\nreleased from sco_chan_del() and sco_sock_destruct(), exactly once. The\nsco_conn no longer owns an hci_conn reference, so sco_conn_add() stops\nconsuming one and sco_connect() drops the hci_connect_sco() reference on\nevery path; sco_connect_cfm() no longer needs its hci_conn_hold() dance."
}
],
"metrics": [
{
"cvssV3_1": {
"baseScore": 7.1,
"baseSeverity": "HIGH",
"vectorString": "CVSS:3.1/AV:A/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"version": "3.1"
},
"scenarios": [
{
"lang": "en",
"value": "AV:A - An in-range peer\u0027s Bluetooth SCO/eSCO data enters as HCI_SCODATA_PKT through hci_recv_frame() \u2192 hci_rx_work() \u2192 hci_scodata_packet() \u2192 the patched sco_recv_scodata(). The radio-range transport makes the vector Adjacent.\nAC:H - Peer-induced Disconnection Complete runs on the same ordered HCI workqueue and calls sco_conn_del() under hdev-\u003elock, so it cannot create this race. Exploitation must instead coincide with local close()/shutdown() freeing the sco_conn outside that lock, timing the peer cannot control.\nPR:N - hci_scodata_packet() and sco_recv_scodata() impose no peer credential or capability check once a SCO/eSCO handle exists. For inbound setup, sco_connect_ind() checks only for a listening SCO socket, not authentication.\nUI:R - The last reference must be dropped through victim-side sco_sock_release() or sco_sock_shutdown() while peer data is received. Because peer-driven sco_disconn_cfm() is serialized against receive processing, a separate victim socket teardown is required.\nS:U - The stale hcon-\u003esco_data pointer corrupts a freed sco_conn inside the host Bluetooth kernel stack; it does not cross a VM, IOMMU, or other security-authority boundary.\nC:H - After sco_conn_hold_unless_zero() revives reclaimed storage, sco_recv_frame() reads the reused conn-\u003esk pointer and socket state. Heap grooming can therefore turn the sco_conn UAF into kernel-memory disclosure.\nI:H - kref_get_unless_zero() performs a four-byte atomic increment in the freed sco_conn, followed on success by spinlock and kref operations on reclaimed storage. Reuse can convert these writes into kernel heap corruption and control-flow hijacking.\nA:H - The demonstrated stale reference causes a KASAN slab-use-after-free write in sco_conn_hold_unless_zero() from hci_rx_work; such corruption can produce an oops or kernel panic."
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-10-24T14:09:59.382Z",
"orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"shortName": "Linux"
},
"references": [
{
"url": "https://git.kernel.org/stable/c/b108ea7ebba147465f4158d8133f0e8f013762ed"
},
{
"url": "https://git.kernel.org/stable/c/8a98d58f6cfe70d51138cd9ce894e72671d95f8a"
},
{
"url": "https://git.kernel.org/stable/c/816fb1590a4c8cf8d05cd076057616be02e276f0"
}
],
"title": "Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata()",
"x_generator": {
"engine": "bippy-1.2.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"assignerShortName": "Linux",
"cveId": "CVE-2026-99011",
"datePublished": "2026-10-23T12:20:36.460Z",
"dateReserved": "2026-09-25T10:25:14.385Z",
"dateUpdated": "2026-10-24T14:09:59.382Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"vulnerability-lookup:meta": {
"epss": {
"cve": "CVE-2026-99011",
"date": "2026-10-24",
"epss": "0.00206",
"percentile": "0.1016"
},
"nvd": {
"cve": {
"affected": [
{
"affectedData": [
{
"defaultStatus": "unaffected",
"product": "Linux",
"programFiles": [
"net/bluetooth/sco.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"lessThan": "b108ea7ebba147465f4158d8133f0e8f013762ed",
"status": "affected",
"version": "e6720779ae612a14ac4ba7fe4fd5b27d900d932c",
"versionType": "git"
},
{
"lessThan": "8a98d58f6cfe70d51138cd9ce894e72671d95f8a",
"status": "affected",
"version": "e6720779ae612a14ac4ba7fe4fd5b27d900d932c",
"versionType": "git"
},
{
"lessThan": "816fb1590a4c8cf8d05cd076057616be02e276f0",
"status": "affected",
"version": "e6720779ae612a14ac4ba7fe4fd5b27d900d932c",
"versionType": "git"
}
]
},
{
"defaultStatus": "affected",
"product": "Linux",
"programFiles": [
"net/bluetooth/sco.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"status": "affected",
"version": "6.13"
},
{
"lessThan": "6.13",
"status": "unaffected",
"version": "0",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.18.*",
"status": "unaffected",
"version": "6.18.57",
"versionType": "semver"
},
{
"lessThanOrEqual": "7.2.*",
"status": "unaffected",
"version": "7.2.11",
"versionType": "semver"
},
{
"lessThanOrEqual": "*",
"status": "unaffected",
"version": "7.3",
"versionType": "original_commit_for_fix"
}
]
}
],
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}
],
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nBluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata()\n\nsco_recv_scodata() upgrades the weak hcon-\u003esco_data back-pointer to a\nstrong reference under hdev-\u003elock:\n\n hci_dev_lock(hdev);\n hcon = hci_conn_hash_lookup_handle(hdev, handle);\n ...\n conn = sco_conn_hold_unless_zero(hcon-\u003esco_data);\n hci_dev_unlock(hdev);\n\nbut the pointer is cleared from the other side without that lock. When\nthe last sco_conn reference is dropped, sco_conn_free() ran\n\n conn-\u003ehcon-\u003esco_data = NULL;\n\nwith no hdev-\u003elock held, so the RX path could read hcon-\u003esco_data and\ncall kref_get_unless_zero() on an sco_conn that was concurrently freed:\n\n BUG: KASAN: slab-use-after-free in sco_conn_hold_unless_zero+0xbe/0x160\n Write of size 4 by task kworker/u17:0\n Workqueue: hci0 hci_rx_work\n Call Trace:\n sco_conn_hold_unless_zero+0xbe/0x160\n sco_recv_scodata+0x13f/0x490\n hci_rx_work+0x3af/0x730\n\nkref_get_unless_zero() only guards against a zero refcount, not against\nthe backing memory already being freed.\n\nGive hcon-\u003esco_data an actual reference on the sco_conn it points to, so\nthe object cannot be freed while the pointer is still installed, and only\nclear and drop it from sco_conn_del(), which runs under hdev-\u003elock (its\ncallers, sco_connect_cfm() and sco_disconn_cfm(), hold it). The reader in\nsco_recv_scodata() also takes hdev-\u003elock, so the store and the read are\nnow serialised: the RX path either observes NULL or a reference that is\nguaranteed to stay valid until it drops its own.\n\nsco_conn_add() no longer hands its kref_init() reference to the caller as\nthe connection\u0027s only reference; that initial reference is the one owned\nby hcon-\u003esco_data, and callers get their own via sco_conn_hold().\n\nBecause the sco_conn can now outlive the socket (the association keeps it\nalive until the link goes down), the hci_conn can no longer be dropped\nfrom sco_conn_free() without regressing socket close: closing a connected\nSCO socket must still tear the link down. Move hci_conn ownership to the\nsocket instead: __sco_chan_add() takes an hci_conn reference and it is\nreleased from sco_chan_del() and sco_sock_destruct(), exactly once. The\nsco_conn no longer owns an hci_conn reference, so sco_conn_add() stops\nconsuming one and sco_connect() drops the hci_connect_sco() reference on\nevery path; sco_connect_cfm() no longer needs its hci_conn_hold() dance."
}
],
"id": "CVE-2026-99011",
"lastModified": "2026-10-24T14:16:52.047",
"metrics": {
"cvssMetricV31": [
{
"cvssData": {
"attackComplexity": "HIGH",
"attackVector": "ADJACENT_NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 7.1,
"baseSeverity": "HIGH",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "REQUIRED",
"vectorString": "CVSS:3.1/AV:A/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
"version": "3.1"
},
"exploitabilityScore": 1.2,
"impactScore": 5.9,
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"type": "Secondary"
}
]
},
"published": "2026-10-23T13:17:23.740",
"references": [
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/816fb1590a4c8cf8d05cd076057616be02e276f0"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/8a98d58f6cfe70d51138cd9ce894e72671d95f8a"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/b108ea7ebba147465f4158d8133f0e8f013762ed"
}
],
"sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"vulnStatus": "Received"
}
}
}
}
Loading…
Loading…
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
Loading timeline…
Loading…
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Loading…
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.