CVE-2026-19936
Executive Summary
CVE-2026-19936 is a race condition (CWE-362) in the Bluetooth Mesh Access-layer delayable message queue of the Zephyr RTOS, located in subsys/bluetooth/mesh/delayable_msg.c. Two cooperative threads — the Bluetooth host RX thread running bt_mesh_delayable_msg_manage() and the system workqueue running delayable_msg_handler() — share three intrusive lists (busy_ctx, free_ctx, free_chunks) and one k_work_delayable without synchronization, allowing one context to observe torn list state while the other blocks mid-operation. A network member holding the NetKey and a bound AppKey can drive inbound access-layer traffic to control occupancy of the 4-entry context pool and 40-entry chunk pool, triggering the purge path and NULL-dereference conditions that crash the device. Successful exploitation yields a high-availability impact (denial of service) on affected Bluetooth Mesh nodes, scoring CVSS 4.8 (AV:A/AC:H/PR:L/UI:N/S:U/C:N/I:N/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 class is a classic unsynchronized shared-state race between two cooperative execution contexts in an RTOS. The shared resources are three intrusive singly-linked lists — busy_ctx (contexts currently parked), free_ctx (available contexts), and free_chunks (available message chunks) — plus a single k_work_delayable. Neither context holds a lock or disables preemption while mutating these structures.
The producer path bt_mesh_delayable_msg_manage() executes on the Bluetooth host RX thread. Crucially, it can block while the lists are in an intermediate state: it calls bt_rand() and later bt_mesh_access_send(), both of which may yield the CPU mid-mutation. The consumer path delayable_msg_handler() executes on the system workqueue and also blocks inside bt_mesh_access_send(). Because both contexts can be preempted or block at these points, the other context is free to run and observe partially-updated list state — the "torn state" described in the advisory.
Two concrete coding defects are identified in the description:
delayable_msg_handler()consumed the return value ofsys_slist_get()onbusy_ctxwithout a NULL check. When the list is concurrently emptied (for example by the purge path),sys_slist_get()can return NULL, and the unchecked dereference leads to a crash.allocate_delayable_msg_ctx()first testedsys_slist_is_empty()onfree_ctxand then assumed that a subsequent, separatesys_slist_get()would succeed. This is a time-of-check-to-time-of-use (TOCTOU) pattern: between the emptiness check and the get, the other context can drain the list, so the get returns NULL and the assumption is violated.
The attack surface is broad because the relevant Kconfig options — CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG and CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED — default to y. Consequently, every model response to a received mesh message is parked on this queue, meaning the vulnerable enqueuer code runs as a direct, unavoidable consequence of inbound access-layer traffic. An attacker therefore does not need a special trigger; ordinary model responses route through the vulnerable path.
Resource exhaustion is the lever. The context pool holds 4 entries and the chunk pool holds 40 entries. A peer controlling arrival rate, response size, and destination address can drive occupancy of both pools. When the chunk pool is exhausted, bt_mesh_delayable_msg_manage() is forced down the purge path, which sends and releases the only queued message and leaves busy_ctx empty — creating exactly the window where delayable_msg_handler()'s unchecked sys_slist_get() returns NULL. No public PoC or exploit code is available; the mechanism above is derived strictly from the NVD description.
Exploitation Scenarios
No public PoC is available; the attack chain below is inferred from the vulnerability class (unsynchronized intrusive-list race) and the specific behavioral facts stated in the NVD description. No function names, endpoints, or parameters beyond those in the description are asserted.
Reconnaissance / target identification. The attacker must first be a legitimate or compromised network member — the description explicitly requires possession of the NetKey and a bound AppKey. Reconnaissance therefore consists of gaining access to mesh network credentials (e.g., via provisioning abuse, key leakage, or a compromised node), then identifying target nodes running affected Zephyr RTOS firmware that respond to access-layer messages. Any node with
CONFIG_BT_MESH_ACCESS_DELAYABLE_MSGenabled (the default) is a candidate.Triggering the flaw class. Once messaging is permitted, the attacker sends access-layer messages that cause a model to generate responses. Because every model response is parked on the delayable message queue, inbound traffic directly drives the vulnerable enqueuer on the RX thread. The attacker manipulates arrival rate, response size, and destination address to control how the 4-entry
free_ctxpool and 40-entryfree_chunkspool are consumed. Rapid or coalesced bursts push occupancy to exhaustion.Exploitation / execution method (vulnerability-class level). By saturating the pools, the attacker forces
bt_mesh_delayable_msg_manage()onto the purge path, which sends and releases the queued message and leavesbusy_ctxempty. The system workqueue concurrently runsdelayable_msg_handler(); the timing window created by the purge path is where the two identified defects manifest — the uncheckedsys_slist_get()onbusy_ctx(NULL dereference) and the TOCTOU assumption inallocate_delayable_msg_ctx()followingsys_slist_is_empty(). The race requires precise interleaving (hence AC:H in the CVSS vector) but not a crafted memory-corruption payload. The technique targets the allocation/resource pool rather than injecting data.Post-exploitation impact. The realistic outcome is a device crash / reboot loop of the mesh node — a denial of service. The description does not suggest memory corruption leading to code execution; the defects are a missing NULL check and a TOCTOU assumption, which produce fault conditions, not controllable write primitives. Repeated triggering can sustain a DoS on targeted nodes. If a single node acts as a relay or model server for a mesh region, its loss can degrade message routing for dependent nodes. No privilege escalation or data confidentiality impact is described.
Impact Assessment
The CVSS v3.1 vector is CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H, scoring 4.8 (Medium). Subscore interpretation:
- AV:A (Adjacent Network) — the attacker must be on the same Bluetooth mesh network (adjacent/within radio range and a network member).
- AC:H (High) — exploitation depends on winning a timing race between the RX thread and the workqueue, requiring favorable interleaving of pool exhaustion and blocking calls.
- PR:L (Low) — the attacker requires the NetKey and a bound AppKey, i.e., legitimate or compromised network credentials rather than none.
- UI:N (None) — no victim user interaction is required; inbound traffic alone drives the enqueuer.
- S:U (Unchanged) — impact is confined to the vulnerable component.
- C:N / I:N — no confidentiality or integrity impact is described.
- A:H (High) — the crash/DoS outcome represents a total loss of availability of the affected node.
Blast radius and business impact. The affected systems are Zephyr RTOS Bluetooth Mesh devices — embedded IoT endpoints, lighting controllers, sensors, building-automation nodes, and any Zephyr-based mesh deployment. Because the delayable message config defaults to y, exposure is broad across the ecosystem rather than limited to opt-in builds. Business impact centers on availability: denial of service to mesh nodes can interrupt building automation, lighting, industrial monitoring, and similar deployments. The high attack condition (AC:H) and low-privileged-but-authenticated requirement (PR:L) mean exploitation is non-trivial and insider/credential-dependent, reducing mass-exploitation likelihood — reflected in the UNPATCHED status with no KEV listing and no public exploit. There is no evidence of exploit-in-the-wild, and EPSS has not yet scored this CVE.
Detection Guidance
Detection for an RTOS-internal race is inherently indirect: there is no network signature unique to the flaw, and no PoC exists. The following rules target the preconditions (mesh credential use, resource-exhaustion traffic patterns) and host-side crash indicators (firmware faults in mesh functions). All function names referenced are taken verbatim from the NVD description.
Sigma Rule
title: Zephyr Bluetooth Mesh Node Repeated Crash / Fault in Delayable Message Path
id: 7f3c1a92-0b6e-4d2a-9c11-5e8a1b2c3d40
status: experimental
description: Detects repeated firmware fault or reboot events on Zephyr Bluetooth Mesh nodes consistent with race-condition crashes in the access-layer delayable message queue (CVE-2026-19936).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-19936
author: valtersit.com
date: 2026-01-01
logsource:
product: linux
service: kernel
detection:
keywords_fault:
- 'delayable_msg_handler'
- 'allocate_delayable_msg_ctx'
- 'bt_mesh_delayable_msg_manage'
- 'FATAL ERROR'
- 'ZEPHYR FATAL ERROR'
crash_markers:
- 'NULL pointer dereference'
- 'K_ERR_CPU_EXCEPTION'
- 'Halting system'
condition: keywords_fault and crash_markers
falsepositives:
- Legitimate firmware bug unrelated to exploitation
- Debug builds with verbose mesh logging
level: medium
tags:
- attack.t1499
- cve.2026.19936
YARA Rule
rule CVE_2026_19936_Zephyr_Mesh_Delayable_Msg_Race
{
meta:
description = "Detects Zephyr RTOS firmware binaries referencing the Bluetooth Mesh access-layer delayable message queue functions associated with CVE-2026-19936"
author = "valtersit.com"
date = "2026-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-19936"
cve = "CVE-2026-19936"
strings:
$fn1 = "bt_mesh_delayable_msg_manage" ascii
$fn2 = "delayable_msg_handler" ascii
$fn3 = "allocate_delayable_msg_ctx" ascii
$path = "subsys/bluetooth/mesh/delayable_msg.c" ascii
$cfg1 = "CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG" ascii
$cfg2 = "CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED" ascii
condition:
(uint16(0) == 0x5A4D or $fn1 or $fn2) and
(1 of ($fn1, $fn2, $fn3, $path, $cfg1, $cfg2))
}
Suricata IDS Rule
alert udp any any -> any 15000 (msg:"CVE-2026-19936 Possible Bluetooth Mesh Access-Layer Response Flood (Zephyr delayable msg queue exhaustion)"; flow:stateless; threshold:type both, track by_src, count 200, seconds 5; classtype:attempted-dos; reference:cve,2026-19936; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-19936; sid:20269936; rev:1;)
Note: Bluetooth Mesh access-layer traffic is normally transported over BLE, not IP. This rule is provided for deployments that tunnel or bridge mesh traffic over UDP (e.g., in lab or gateway environments); there is no standard routable IP signature for native mesh access messages.
Elastic Detection
sequence by host.id with maxspan=60s
[ firmware where process.name : "*mesh*" and message : "*delayable_msg_handler*" ]
[ firmware where message : ("*ZEPHYR FATAL ERROR*" or "*NULL pointer dereference*" or "*CPU exception*") ]
Splunk SPL Query
index=firmware OR index=iot sourcetype=zephyr_mesh_logs
| search ("delayable_msg_handler" OR "allocate_delayable_msg_ctx" OR "bt_mesh_delayable_msg_manage" OR "ZEPHYR FATAL ERROR" OR "NULL pointer dereference")
| stats count AS event_count, dc(host) AS affected_nodes, latest(_time) AS last_seen BY host
| where event_count > 3
| table host, event_count, affected_nodes, last_seen
Wazuh OSSEC Rule
<group name="zephyr,bluetooth_mesh,">
<rule id="199360" level="0">
<decoded_as>syslog</decoded_as>
<match>ZEPHYR FATAL ERROR|delayable_msg_handler|allocate_delayable_msg_ctx|bt_mesh_delayable_msg_manage</match>
<description>Zephyr Bluetooth Mesh delayable message fault indicator (CVE-2026-19936)</description>
</rule>
<rule id="199361" level="10" frequency="3" timeframe="120">
<if_matched_sid>199360</if_matched_sid>
<same_source_ip />
<description>Repeated Zephyr Bluetooth Mesh crash consistent with CVE-2026-19936 race-condition DoS</description>
<mitre>
<id>T1499</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). No vendor fix or workaround is documented. The following measures are defensive recommendations derived from the flaw mechanism, not vendor-supplied fixes.
1) Immediate mitigations
- Restrict mesh credentials. The description states the attacker must hold the NetKey and a bound AppKey. Treat NetKey/AppKey material as high-value secrets: rotate keys if compromise is suspected, audit which nodes hold binding keys, and remove unused bindings.
- Reduce attack surface via configuration. Disable the vulnerable feature where mesh model responses are not required by setting
CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG=n(andCONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED=n). Note these default toy; explicitly disabling them removes responses from the vulnerable queue on builds that do not need it. - Rate-limit inbound access-layer traffic at gateway/relay boundaries to reduce the ability to exhaust the 4-entry context pool and 40-entry chunk pool.
- Add watchdog-based auto-recovery so nodes that fault are rebooted promptly, limiting sustained DoS.
2) Patch / upgrade steps
- No patch is currently available from any tracked source. Monitor the Zephyr project's
subsys/bluetooth/mesh/delayable_msg.cand its advisory channels for a fix. When released, the expected fix class is synchronization of the shared lists andk_work_delayable(locking or serializing the two contexts) plus correctness fixes: a NULL check on thesys_slist_get()result indelayable_msg_handler(), and eliminating the TOCTOU assumption inallocate_delayable_msg_ctx()aftersys_slist_is_empty(). Validate any candidate patch against these specific defects. - Until a patch ships, treat affected firmware as unpatched and rely on compensating controls above.
3) Long-term hardening
- Do not rely on cooperative scheduling for shared state. Design host/workqueue interactions with explicit synchronization (mutexes or serialized access) rather than trusting block-point atomicity.
- Eliminate TOCTOU patterns — check-and-use on intrusive lists should be a single operation that handles the empty case, with mandatory NULL handling on every
sys_slist_get()result. - Security review of resource pools for embedded mesh stacks; bound and monitor pool occupancy and alert on sustained exhaustion.
- Supply-chain visibility: track the Zephyr version in every mesh product and subscribe to Zephyr security advisories so future fixes to
delayable_msg.care applied promptly.
References
- NVD — CVE-2026-19936: https://nvd.nist.gov/vuln/detail/CVE-2026-19936
- Zephyr Project security/advisory channels (monitor for fix to
subsys/bluetooth/mesh/delayable_msg.c): https://github.com/zephyrproject-rtos/zephyr/security - MITRE CWE-362 — Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'): https://cwe.mitre.org/data/definitions/362.html
- MITRE ATT&CK T1499 — Endpoint Denial of Service: https://attack.mitre.org/techniques/T1499/
- CISA Known Exploited Vulnerabilities Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No threat actor campaigns, exploit-in-the-wild evidence, public PoC, or Nuclei template are known for this CVE at the time of writing. It is not listed in CISA KEV, and EPSS has not yet assigned a score.
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.