
Proof of concept for CVE-2026-10672, an out-of-bounds read in Zephyr RTOS's
LwM2M firmware-update pull client (subsys/net/lib/lwm2m/lwm2m_pull_context.c).
lwm2m_pull_context_start_transfer() in lwm2m_pull_context.cmemcpy(context.uri, uri, LWM2M_PACKAGE_URI_LEN) copies exactly
128 bytes into char uri[128] with no NUL terminator when the server-supplied
Package URI (/5/0/1) is ≥ 128 bytes. Subsequent strlen(context.uri),
http_parser_parse_url(), and the CoAP PROXY_URI option append then read past
the buffer into adjacent struct memory (is_firmware_uri, the result_cb /
write_cb function pointers, and the DTLS connection context). The over-read
bytes are exfiltrated in the outbound CoAP request.context.uri[128] (CONFIG_LWM2M_SWMGMT_PACKAGE_URI_LEN, default 128;
LWM2M_PACKAGE_URI_LEN is #defined to it)99a164df5cea5af76e32b57c6d51854f018969a2
— adds strlen(uri) >= sizeof(context.uri) → -ENOMEM and switches to strcpy().| File | Purpose |
|---|---|
poc.c | Standalone C reproduction of the vulnerable/fixed code paths. Faithfully re-declares (the buffer plus the adjacent fields that get over-read) and the leaky CoAP consumer. |
gcc -O0 -g -o poc poc.c
./poc
Expected: a 200-byte Package URI produces a CoAP PROXY_URI option of 141 bytes
— the 128-byte URI plus 13 bytes leaked from context.is_firmware_uri,
struct padding, and the result_cb/write_cb function pointers. The fixed code
path rejects the URI with -ENOMEM and copies nothing.
gcc -O0 -g -fsanitize=address -o poc-asan poc.c
./poc-asan
The probe allocates exactly 128 bytes, fills them with non-NUL bytes (mirroring a
full context.uri with no terminator) and calls strlen():
ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 129 at 0x...
0x... is located 0 bytes after 128-byte region [...,0x...)
# Build and inspect the CoAP packets without sending:
python3 lwm2m_evil_server.py --dry-run --uri-len 200
# Send to a vulnerable client (NoSec CoAP, UDP/5683):
python3 lwm2m_evil_server.py --target 10.0.0.42 --port 5683 --uri-len 200 --listen 2
The script issues a CoAP PUT /5/0/1 (LwM2M Write of the Package URI
resource) followed by a CoAP POST /5/0/2 (LwM2M Execute Update, which
starts the firmware pull and triggers the bug). In production LwM2M the session
runs over DTLS (UDP/5684); the attacker in scope is a malicious/compromised
management server, or an on-path adversary when DTLS server authentication is
not enforced.
For authorized security research and educational purposes only. Do not use these tools against devices you do not own or have explicit permission to test.
struct firmware_pull_contexturi[128]PROXY_URIlwm2m_evil_server.py | Minimal CoAP/LwM2M server that delivers the over-sized Package URI to /5/0/1 of a vulnerable client over UDP (NoSec mode) — the network-delivery half of the attack. No external dependencies. |