CVE-2026-13480 Overview
CVE-2026-13480 is an out-of-bounds read vulnerability in the Zephyr RTOS LoRaWAN Fragmented Data Block Transport (TS004) service. The defect resides in frag_transport_package_callback() inside subsys/lorawan/services/frag_transport.c. The handler parses downlink command bytes without confirming that enough payload bytes remain before each field access. An authenticated party holding valid LoRaWAN session keys can craft a downlink that causes the fragment decoder to read beyond the static MacCtx.RxPayload buffer. Adjacent memory bytes are copied into decoder buffers and the FUOTA flash image, but no direct disclosure channel is exposed. The issue is classified under [CWE-20] Improper Input Validation.
Critical Impact
A caller with valid session keys can trigger a bounded out-of-bounds read of up to ~232 bytes past RxPayload, potentially corrupting FUOTA flash images with adjacent memory contents.
Affected Products
- Zephyr RTOS LoRaWAN subsystem (subsys/lorawan/services/frag_transport.c)
- Devices implementing LoRaWAN TS004 Fragmented Data Block Transport with FUOTA
- Firmware built against the loramac-node MAC layer using MacCtx.RxPayload
Discovery Timeline
- 2026-08-26 - CVE-2026-13480 published to NVD
- 2026-08-26 - Last updated in NVD database
Technical Details for CVE-2026-13480
Vulnerability Analysis
The LoRaWAN TS004 Fragmented Data Block Transport handler walks downlink command bytes in a loop bounded only by rx_pos < len. After consuming a one-byte command identifier, the handler casts rx_buf + rx_pos to a 10-byte struct frag_transport_setup_req. For a DATA_FRAGMENT command, it passes &rx_buf[rx_pos] to the fragment decoder, which reads exactly ctx.frag_size bytes with no remaining-length check.
The fragment size is attacker-controlled through a preceding FRAG_SESSION_SETUP command. It is capped at CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_FRAG_SIZE, defaulting to 232 bytes. Because rx_buf aliases the 255-byte static MacCtx.RxPayload buffer in the loramac-node MAC layer, out-of-bounds bytes originate from adjacent static memory rather than stack or heap regions.
Root Cause
The root cause is missing bounds validation before both the struct cast and the fragment decode. The loop trusts len as an upper bound on the current position, but never verifies that sizeof(struct frag_transport_setup_req) or ctx.frag_size bytes actually remain in the buffer.
Attack Vector
The handler only executes on downlinks that have already passed LoRaWAN frame MIC verification and FRMPayload decryption. Exploitation requires possession of the device's session keys, meaning the attacker is either the FUOTA server or a party who has compromised those keys. An attacker crafts a downlink padded with mismatched-index DATA_FRAGMENT filler commands that each advance rx_pos by three bytes, then appends one matching-index fragment near the end of the payload. The decoder then reads up to roughly frag_size bytes past the end of RxPayload, copying adjacent static memory into the decoder buffers and FUOTA flash image. No out-of-bounds bytes are returned to the sender because the only uplink emitted is a status answer carrying fragment counts.
case FRAG_TRANSPORT_CMD_FRAG_SESSION_SETUP: {
+ if ((len - rx_pos) < sizeof(struct frag_transport_setup_req)) {
+ LOG_ERR("FragSessionSetupReq too short");
+ return;
+ }
const struct frag_transport_setup_req *req =
(const void *)(rx_buf + rx_pos);
uint8_t frag_session = req->frag_session & 0x3F;
Source: Zephyr commit 237309ea7c46ce85cedebf33dfea639aa2f5e2ca
Detection Methods for CVE-2026-13480
Indicators of Compromise
- Downlink frames containing long runs of DATA_FRAGMENT commands with fragment indices that do not match any active session.
- FUOTA flash images that contain byte sequences resembling MAC-layer state rather than expected firmware content.
- Repeated FRAG_SESSION_SETUP commands establishing large frag_size values close to CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_FRAG_SIZE.
Detection Strategies
- Instrument the LoRaWAN stack to log downlink payload length and cumulative rx_pos for each parsed command, and flag payloads where a DATA_FRAGMENT command consumes bytes beyond len.
- Compare received FUOTA image hashes against publisher-signed reference hashes to detect flash images corrupted by out-of-bounds bytes.
- Audit FUOTA server logs for anomalous downlink construction patterns, particularly filler commands that produce no answer uplink.
Monitoring Recommendations
- Monitor LoRaWAN Network Server logs for anomalous FRAG_SESSION_SETUP parameter values and unexpected fragment index sequences.
- Track FUOTA session outcomes and correlate failed image validations with the downlink sequences that preceded them.
- Alert on any deployment of firmware to devices that has not been signed and verified by the intended FUOTA publisher.
How to Mitigate CVE-2026-13480
Immediate Actions Required
- Update Zephyr RTOS to a version that includes commit 237309ea7c46ce85cedebf33dfea639aa2f5e2ca, which adds remaining-length guards before each access in frag_transport_package_callback().
- Rotate LoRaWAN device session keys (AppSKey, NwkSKey) for any device where key compromise is suspected.
- Restrict FUOTA server access to authorized operators and enforce mutual authentication between application servers and the FUOTA service.
Patch Information
The fix is applied in subsys/lorawan/services/frag_transport.c and validates that (len - rx_pos) covers sizeof(struct frag_transport_setup_req) before performing the struct cast. Equivalent guards are added before the DATA_FRAGMENT decoder call. See GitHub Security Advisory GHSA-845m-2m84-g5h2 for full advisory details and affected release ranges.
Workarounds
- Reduce CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_FRAG_SIZE in device Kconfig to limit the maximum out-of-bounds read length until firmware can be updated.
- Disable the Fragmented Data Block Transport service on devices that do not require FUOTA by unsetting CONFIG_LORAWAN_FRAG_TRANSPORT.
- Deploy signed and integrity-verified FUOTA images so that any adjacent-memory contamination during fragment reassembly fails signature validation before flash activation.
# Kconfig hardening example
CONFIG_LORAWAN_FRAG_TRANSPORT=n
# or, if FUOTA is required, cap fragment size
CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_FRAG_SIZE=64
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

