CVE-2026-19938
Executive Summary
CVE-2026-19938 is a use-after-free vulnerability (CWE-416) in the Bluetooth host ATT transmit path of the Zephyr RTOS Bluetooth stack, located in chan_send() within subsys/bluetooth/host/att.c. When an application issues a GATT Signed Write Command over a connection for which no local CSRK exists, the BT_ATT_OP_SIGNED_WRITE_CMD branch frees the transmit net_buf despite the documented ownership contract requiring the caller to retain ownership on failure, causing the buffer to be re-queued, dereferenced, and freed a second time. Affected systems are Bluetooth Low Energy devices running the Zephyr Bluetooth host for which an adjacent peer can negotiate a pairing state that leaves no local CSRK. Impact is availability-focused with a required adjacent attack position, consistent with CVSS 5.9 (AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:H).
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability is an ownership-contract violation that manifests as a double-free / use-after-free in the Bluetooth host attribute protocol (ATT) transmit path.
The buffer ownership contract. The function chan_send() in subsys/bluetooth/host/att.c documents a contract that the caller retains ownership of the net_buf on failure; every other error exit in the function implements this contract. The BT_ATT_OP_SIGNED_WRITE_CMD branch is the exception: when bt_smp_sign() returns an error, that branch calls net_buf_unref(buf) and then returns the error to the caller. Because the caller still believes it owns the buffer, the subsequent caller logic acts on the documented contract and manipulates an already-freed object.
What the callers do with the failed buffer (per the description).
process_queue()re-queues the buffer withk_queue_prepend().bt_att_chan_send_rsp()puts it back onchan->tx_queue.bt_att_chan_req_send()restores it into the request.att_req_retry()unreferences it.
Because these actions assume ownership, the already-freed buffer is re-queued, later dereferenced, and eventually freed again — the classic double-free use-after-free pattern.
Trigger condition. An ATT Signed Write Command is produced when an application calls bt_gatt_write_without_response_cb() with the sign flag set on an unencrypted connection. bt_smp_sign() fails whenever no local CSRK exists for the peer (returns -ENOENT). Whether a local CSRK exists is a negotiated property: smp_distribute_keys() stores a local CSRK only when the peer's pairing key-distribution field requests the signing key AND bonding was agreed. Consequently a peer can, by its own negotiation choices, cause the victim to lack a local CSRK.
Peer-controlled preconditions. The description enumerates the peer behaviors that force the failing path:
- pair without accepting the CSRK,
- pair with No Bonding,
- remain unpaired,
- or keep the link unencrypted.
In any of these states, the victim's next signed write takes the bt_smp_sign() error path and triggers the ownership violation.
Aggravating factor — net_buf node reuse. struct net_buf's node field is simultaneously the linkage word for the ATT TX FIFO, for the deferred-destroy list used by the att_pool destroy callback (the NVD description truncates here). This aliasing means a freed buffer that is incorrectly re-queued can corrupt multiple intrusive lists and deferred-destroy structures at once — widening the corruption beyond a single FIFO.
Attack surface and reachability. The exposed primitive is an adjacent (AV:A) Bluetooth Low Energy interaction. No local account or user interaction is required (PR:N, UI:N). The high attack complexity (AC:H) and network-adjacency constraint reflect the negotiated pairing-state precondition and timing needed to land the signed write on the failing path.
Insufficient technical detail available on the precise schedule (interrupt context vs. workqueue) in which the re-queue and second free occur; the NVD description truncates at the deferred-destroy list description. The class of bug, however, is unambiguous: improper ownership handling leading to a double-free / use-after-free.
Exploitation Scenarios
No public PoC or exploit code is available; the attack chain below is inferred from the vulnerability class and the mechanism described in the NVD Description. All named functions are taken verbatim from the description.
Reconnaissance / target identification. An adversary within Bluetooth radio range identifies a target device running the Zephyr Bluetooth host that exposes a GATT server supporting write-without-response operations (the transport used for signed writes). The adversary does not require credentials or pairing with the victim.
Precondition establishment (peer-controlled). The attacker negotiates pairing in a state that prevents the victim from storing a local CSRK. Per the description this can be achieved by pairing without accepting the CSRK, pairing with No Bonding, remaining unpaired, or keeping the link unencrypted. In each case
smp_distribute_keys()does not store a local CSRK for the peer, sobt_smp_sign()will return-ENOENTon any subsequent signed write by the victim.Trigger. The victim application performs a signed write — specifically a call to
bt_gatt_write_without_response_cb()with thesignflag set on the now-unencrypted connection. This produces aBT_ATT_OP_SIGNED_WRITE_CMD.bt_smp_sign()fails with-ENOENTbecause no local CSRK exists, and the buggy branch inchan_send()callsnet_buf_unref(buf)while still returning the error to a caller that believes it owns the buffer.Post-trigger corruption. The caller then operates on the freed buffer as though it were valid:
process_queue()prepends it to the TX queue,bt_att_chan_send_rsp()restores it tochan->tx_queue,bt_att_chan_req_send()restores it into the request, oratt_req_retry()unreferences it. The buffer is re-queued, later dereferenced, and eventually freed a second time. Because thenet_bufnode field is shared between the ATT TX FIFO linkage and the deferred-destroy list used by the att_pool destroy callback, the double-free can corrupt multiple intrusive data structures.Impact realization. Practical outcomes of a double-free/UAF in a constrained RTOS Bluetooth stack include memory corruption, heap metadata corruption, list corruption leading to crash, denial of service (connection drop, stack fault, or device reset), and — in the weakest case — limited integrity effects as scored (I:L). Given the availability weight of the CVSS vector (A:H), the most reliably demonstrable impact is remote (adjacent) denial of service. Escalation to code execution is conceivable for a UAF of this class but is not established by any available evidence and is not asserted here.
Impact Assessment
- Confidentiality (C:N). The vector assigns no confidentiality impact; the described mechanism exposes no read primitive.
- Integrity (I:L). The vector indicates low integrity impact. Structurally, the double-free and intrusive-list aliasing could corrupt in-memory state, but the description does not demonstrate a controlled write or data modification.
- Availability (A:H). The dominant impact. A double-free/UAF in the ATT transmit path can crash the Bluetooth host, drop the connection, or fault the RTOS, producing a denial of service that is repeatable by an adjacent attacker who can re-establish the precondition.
- Attack vector and complexity. AV:A (adjacent) with AC:H (high complexity), reflecting the need to negotiate a CSRK-less pairing state and land the victim's next signed write on the failing path.
- Privileges / user interaction. PR:N and UI:N — no privileges are required and no user interaction is needed.
- Blast radius. Devices running the Zephyr Bluetooth host as an ATT server, especially BLE peripherals with connection-oriented GATT servers: sensors, wearables, medical/IoT endpoints, and embedded controllers. Because the affected code is a widely reused RTOS Bluetooth stack, the affected population can be large even though exploitation is per-device and adjacent. No CISA KEV listing and no known in-the-wild exploitation are evidenced.
Detection Guidance
Sigma Rule
title: Zephyr Bluetooth ATT Signed Write Use-After-Free Trigger Attempt
id: 9f2c7a14-3b6d-4e21-9a0f-cve202619938
status: experimental
description: Detects host-side logging consistent with a failed signed ATT write path that triggers CVE-2026-19938 (net_buf ownership violation / double free in chan_send).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-19938
author: valtersit.com
logsource:
product: zephyr
service: bluetooth
detection:
keywords_bt:
- "bt_smp_sign"
- "BT_ATT_OP_SIGNED_WRITE_CMD"
- "chan_send"
keywords_err:
- "-ENOENT"
- "ENOENT"
- "no local CSRK"
keywords_crash:
- "net_buf_unref"
- "double free"
- "use-after-free"
- "att_pool"
condition: keywords_bt and (keywords_err or keywords_crash)
falsepositives:
- Normal signed-write failures on bonded, CSRK-provisioned peers
- Debug builds with verbose SMP/ATT logging
level: medium
tags:
- attack.t1210
- cve.2026-19938
YARA Rule
rule CVE_2026_19938_Zephyr_ATT_SignedWrite_UAF
{
meta:
description = "Detects Zephyr Bluetooth ATT source/binaries containing the vulnerable signed-write error path described in CVE-2026-19938"
cve = "CVE-2026-19938"
cwe = "CWE-416"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-19938"
author = "valtersit.com"
severity = "medium"
strings:
$att_file = "subsys/bluetooth/host/att.c" ascii wide
$fn_chan = "chan_send" ascii wide
$op_signed = "BT_ATT_OP_SIGNED_WRITE_CMD" ascii wide
$smp_sign = "bt_smp_sign" ascii wide
$unref = "net_buf_unref" ascii wide
$enoent = "-ENOENT" ascii wide
$distribute = "smp_distribute_keys" ascii wide
$signwrite = "bt_gatt_write_without_response_cb" ascii wide
condition:
uint32(0) == 0x464C457F or uint16(0) == 0x5A4D or true
and $fn_chan
and $op_signed
and $smp_sign
and $unref
and ( $att_file or $enoent or $distribute or $signwrite )
}
Suricata IDS Rule
Network-layer detection of unencrypted Bluetooth LE traffic is not observable over IP transport without a BLE capture bridge; the rule below targets a BLE-over-IP bridge/logging gateway and flags the ATT Signed Write Command opcode (0x12) on non-encrypted links.
alert tcp any any -> any any (msg:"CVE-2026-19938 Possible Zephyr BLE ATT Signed Write Command on Unencrypted Link"; flow:to_client,established; content:"|12|"; byte_test:1,=,0x12,0,relative; content:"ATT"; nocase; threshold:type both,track by_src,count 5,seconds 60; classtype:attempted-dos; reference:cve,2026-19938; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-19938; sid:202619938; rev:1;)
Elastic Detection
sequence by host.id with maxspan=30s
[any where process.name : "*bluetooth*" and message : "*BT_ATT_OP_SIGNED_WRITE_CMD*"]
[any where message : ("*bt_smp_sign*" or "*ENOENT*" or "*no local CSRK*")]
[any where message : ("*net_buf_unref*" or "*double free*" or "*use-after-free*" or "*att_pool*")]
Splunk SPL Query
index=embedded OR index=bluetooth sourcetype=zephyr OR sourcetype=syslog
(("BT_ATT_OP_SIGNED_WRITE_CMD" OR "chan_send" OR "bt_gatt_write_without_response_cb")
AND ("bt_smp_sign" OR "ENOENT" OR "no local CSRK" OR "net_buf_unref" OR "double free" OR "att_pool" OR "k_queue_prepend"))
| stats count min(_time) as first_seen max(_time) as last_seen values(host) as victims values(src_mac) as peers by src_mac
| where count >= 1
| convert ctime(first_seen) ctime(last_seen)
| sort - count
Wazuh OSSEC Rule
<group name="bluetooth,zephyr,cve-2026-19938,">
<rule id="2026190" level="10">
<decoded_as>syslog</decoded_as>
<match>BT_ATT_OP_SIGNED_WRITE_CMD|chan_send|bt_gatt_write_without_response_cb</match>
<description>CVE-2026-19938: Zephyr BLE ATT signed write path observed on unencrypted link</description>
<group>attack.t1210,cve.2026.19938,</group>
</rule>
<rule id="2026191" level="12">
<if_sid>2026190</if_sid>
<match>bt_smp_sign|ENOENT|no local CSRK|net_buf_unref|double free|use-after-free|att_pool</match>
<description>CVE-2026-19938: net_buf ownership violation / double-free indicator in ATT transmit path</description>
<group>attack.t1210,cve.2026.19938,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
Immediate mitigations.
- Do not rely on GATT signed writes on connections that may lack a local CSRK. Audit applications that call
bt_gatt_write_without_response_cb()with thesignflag set and, where possible, avoid signed writes on unencrypted links. - Enforce an application-level precondition: only issue signed writes when a local CSRK is present for the peer; gate the write on pairing/bonding state rather than assuming it.
- Restrict the pairing states accepted by coordinating devices: refuse No Bonding and require the signing key (CSRK) to be distributed during pairing so that the failing
-ENOENTpath is unreachable in normal operation. - Reduce attack surface where feasible by limiting Bluetooth discoverability/connectability to trusted peers and by monitoring for pairing attempts that do not distribute a CSRK.
- Do not rely on GATT signed writes on connections that may lack a local CSRK. Audit applications that call
Patch/upgrade steps. No vendor fix is identified by any tracked source. The fix, when available, must correct
chan_send()insubsys/bluetooth/host/att.cso theBT_ATT_OP_SIGNED_WRITE_CMDerror branch honors the documented ownership contract and does NOT callnet_buf_unref(buf)on failure — leaving the caller to perform the single, correct free per the existing contract. Track the upstream Zephyr project for a commit to this file and apply it once released; until then, treat affected firmware as unpatched.Long-term hardening.
- Add static analysis / fuzzing to the ATT TX path with signed-write inputs to catch ownership-contract violations.
- Harden
struct net_bufhandling where thenodefield is aliased between intrusive lists (ATT TX FIFO and the att_pool deferred-destroy list) to avoid cross-list corruption on any double-free. - Require CSRK negotiation as a precondition for accepting or emitting signed writes in the Bluetooth host, removing the "no local CSRK" reachable state.
- Deploy host-side logging for the indicators in the Detection Guidance section and alert on ATT signed-write failures on unencrypted links.
References
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-19938
- CWE-416 — Use After Free: https://cwe.mitre.org/data/definitions/416.html
- Zephyr Project source:
subsys/bluetooth/host/att.c(chan_send()), upstream repository and security advisories (no patched version identified at time of writing) - CISA Known Exploited Vulnerabilities catalog — CVE-2026-19938 is NOT listed; no exploit-in-the-wild evidence is available
- No public PoC, exploit code, or Nuclei template is available for this CVE
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.