CVE-2026-19937: Bluetooth Mesh Access layer permanently leaks delayable-message contexts, disabling all model responses
The Bluetooth Mesh Access layer delayable-message machinery in subsys/bluetooth/mesh/delayablemsg.c manages a static pool of CONFIGBTMESHACCESSDELAYABLEMSGCOUNT message contexts (default 4) threaded onto a freectx or busyctx list. releasedelayablemsgctx() returned a context to freectx only when sysslistfindandremove() found it on busyctx. The chunk-exhaustion error path in btmeshdelayablemsgmanage() releases a context that was already popped off freectx but not yet inserted on busyctx, so the context was appended to neither list and was permanently lost from the pool. Because btmeshdelayablemsginit() runs only once from btmeshinit(), and node reset/suspend only drain busyctx, the loss survives unprovision, re-provision and suspend/resume — it is cleared only by a reboot.
The error path is reached when the chunk pool (CONFIGBTMESHACCESSDELAYABLEMSGCHUNKCOUNT, default 40 chunks) is short of the chunks a new delayed message needs and the oldest pending message cannot be flushed because btmeshaccesssend() returns -EBUSY or -ENOBUFS (all segmented-TX contexts busy, or advertising/segment buffers exhausted). A peer that is provisioned into the mesh network — holding a valid NetKey plus an AppKey or DevKey bound to a server model — can drive both conditions by flooding the victim with requests that elicit segmented responses while withholding the Segment Acknowledgment, which keeps the transmit contexts occupied while queued responses hold the chunk pool. Each further request that arrives in that window leaks one context.
Once the pool is drained, btmeshdelayablemsgmanage() returns -ENOMEM for every subsequent send and btmeshmodelsend() propagates that error with no fallback to an immediate transmit. Since CONFIGBTMESHACCESSDELAYABLEMSG and CONFIGBTMESHACCESSDELAYABLEMSGCTXENABLED are both enabled by default, ctx->rnddelay is set for every received access message, so all replies from Configuration Server, Health Server and application server models are silently dropped. The node keeps receiving and processing traffic but never answers, a persistent denial of service until the device is restarted. There is no memory corruption, information disclosure or integrity impact; releases before the fix compute the chunk count from the transmit buffer capacity rather than its payload length, making chunk-pool starvation — and therefore the leak — considerably easier to provoke.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Operational
Reboot the affected Bluetooth Mesh device to clear the leaked delayable-message contexts and recover from the persistent denial of service.
Event History
Frequently Asked Questions
Which configurations are most susceptible to exhaustion?
The default configuration has four delayable-message contexts and 40 message chunks. The failure path is triggered when a new delayed message needs more chunks than remain available and the oldest pending message cannot be flushed because sending returns -EBUSY or -ENOBUFS.
What runtime conditions are required to trigger the context loss?
A delayed-message allocation must encounter chunk-pool exhaustion while the oldest pending message cannot be sent. The described send failures occur when all segmented-transmit contexts are busy or when advertising or segment buffers are exhausted.
Does resetting or reprovisioning the node restore lost capacity?
No. Lost contexts survive unprovisioning, reprovisioning, and suspend/resume because those operations only drain the busy-context list; the affected context is on neither list. A reboot is the only documented way to clear the loss.