CVE-2026-15891
nicheNULL Pointer Dereference in Zephyr RTOS MQTT-SN Client Allows Remote Denial of Service
The Zephyr RTOS MQTT-SN client's keepalive handler process_ping() in subsys/net/lib/mqtt_sn/mqtt_sn.c discards the result of SYS_SLIST_PEEK_HEAD_CONTAINER, leaving the gateway pointer gw NULL, which is then dereferenced (gw->gw_id) and passed to mqtt_sn_gw_destroy(), ultimately reaching k_mem_slab_free() with a NULL pointer. The flawed branch executes whenever the connected MQTT-SN gateway fails to answer keepalive PINGREQs for the configured number of retries, a condition fully controlled by the remote peer. Because MQTT-SN runs over unauthenticated UDP, a malicious or compromised gateway, or an on-path/adjacent attacker that spoofs a gateway or blackholes the real gateway's PINGRESPs, can remotely trigger the defect without credentials. The impact is a denial of service: with CONFIG_MEM_SLAB_POINTER_VALIDATE enabled the client panics the kernel (k_panic()), while in the default configuration a write through the NULL pointer silently corrupts the memory-slab free list; no attacker-controlled data is written and confidentiality/integrity are unaffected. Any device running a Zephyr build with the MQTT-SN client library is affected; no public PoC exists and the issue is not in CISA KEV, so no exploitation is known.
What to do: Upgrade to a Zephyr build containing the fix (the commit that assigns the SYS_SLIST_PEEK_HEAD_CONTAINER result to gw in process_ping()). As interim mitigations, restrict which hosts can exchange MQTT-SN UDP traffic with your devices to trusted gateway addresses, enable CONFIG_MEM_SLAB_POINTER_VALIDATE so the fault fails fast as an explicit panic instead of silently corrupting the allocator, and audit device firmware configs to confirm whether the MQTT-SN client library is actually enabled.
| Zephyr Project Zephyr RTOS (MQTT-SN client, subsys/net/lib/mqtt_sn/mqtt_sn.c) | — |
Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.
The MQTT-SN client keepalive handler process_ping() in subsys/net/lib/mqtt_sn/mqtt_sn.c removes the gateway record after PINGREQ retries are exhausted. It invoked SYS_SLIST_PEEK_HEAD_CONTAINER(&client->gateways, gw, next) but discarded the result. That macro is a pure expression that does not assign to gw, so gw retained its NULL initializer regardless of the list contents. The code then dereferences the NULL gw (gw->gw_id) and passes it to mqtt_sn_gw_destroy(), reaching k_mem_slab_free(&gateways, NULL). With CONFIG_MEM_SLAB_POINTER_VALIDATE enabled this triggers k_panic(); in the default configuration it performs a write through the NULL pointer ((char )mem = slab->free_list;) and corrupts the slab free list. The outcome is a crash/kernel panic or, on targets where address 0 is writable, silent memory-allocator corruption. The vulnerable branch runs whenever the connected MQTT-SN gateway fails to answer keepalive PINGREQs for the configured number of retries. This condition is controlled by the remote peer: a malicious or compromised gateway, or an on-path/adjacent attacker that advertises itself as a gateway and then stops responding (or blackholes the real gateway's PINGRESPs), forces the client into the defect. MQTT-SN runs over UDP and no authentication is required. The impact is a remotely triggerable denial of service (availability) of the affected MQTT-SN client; there is no attacker-controlled data written. The sibling remover process_advertise() uses SYS_SLIST_FOR_EACH_CONTAINER_SAFE and is not affected. The fix assigns the macro's return value to gw.
- Weakness
- CWE-476
- Vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
In the news0 stories
No ingested article mentions this CVE yet.