cve.bz

CVE-2026-16664 Unchecked serial-recovery image index causes out-of-bounds slot-table read in MCUboot Zephyr port

5.1 mediumEPSS 0.1%

Medium (5.1) in mcu-tools mcuboot. EPSS 0.1% estimated probability of exploitation activity in the next 30 days.

On this page
MCUboot's Zephyr serial-recovery upload handler bs_upload() in boot/boot_serial/src/boot_serial.c decodes the host-supplied image field of an MCUmgr image-upload request into img_num (a full 32-bit value) and latches it on the off == 0 packet without any range check. It then passes img_num straight to flash_area_id_from_multi_image_slot(img_num, 0), which on the Zephyr port resolves to __flash_area_ids_for_slot() in boot/zephyr/include/sysflash/sysflash.h and indexes the static const int all_slots[] table as all_slots[img_num 2]. That table holds only MCUBOOT_IMAGE_NUMBER 2 entries, so any img_num >= MCUBOOT_IMAGE_NUMBER is an out-of-bounds read. The path is reachable by anyone with access to the serial / SMP recovery console, which is unauthenticated by design, and the bad value is supplied before any image signature is verified. The defect is specific to the default non-direct upload path (MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD disabled) on the Zephyr port with the array-backed slot layout (not CONFIG_SINGLE_APPLICATION_SLOT). It is not gated on a multi-image configuration: MCUBOOT_IMAGE_NUMBER defaults to 1, so even a default single-image build is affected for any image >= 1. The MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD path is safe (its flash_area_id_from_direct_image() switch returns -EINVAL for unknown indices). flash_area_id_from_multi_image_slot() takes a signed int image_index while img_num is uint32_t, so the attacker controls the sign of the index as well as its magnitude: an image of 0xFFFFFFFE converts to -2 and reads all_slots[-4], off the front of the table, while large positive values read off the end (CWE-192). (0xFFFFFFFF itself is the "no image given" sentinel and selects image 0.) Either way the index multiply img * 2 is performed in int, so a wild offset yields a bus/hard fault, giving a reliable denial of service of the bootloader during recovery. For moderately out-of-range indices the read returns adjacent .rodata as a garbage flash-area id that is handed to flash_area_open(); this normally fails with MGMT_ERR_EINVAL, but if the garbage id happens to match a valid non-image partition, the subsequent erase/write can target a partition outside the image set (CWE-787). The attacker-supplied value is never echoed back, so there is no information disclosure. The fix is to reject img_num >= BOOT_IMAGE_NUMBER on the off == 0 packet, before the slot lookup. The comparison must be made on the unsigned img_num: an equivalent guard applied after the conversion to int would not reject the negative case above. __flash_area_ids_for_slot() should bounds-check its own arguments as defence in depth. This vulnerability was reported independently twice: by NVIDIA Project Vanessa on 2026-06-22, and by Kai Phan (@kaimandalic) on 2026-07-19 as GHSA-8v33-88p6-jffj, which is closed as a duplicate of this advisory. Both original reports are reproduced in full below.

Severity

CVSS 3.1

5.1 medium
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L
EPSS
0.1% estimated probability of exploitation activity in the next 30 days; 1st percentile. Scored 2026-11-13. A forecast for this CVE across the internet, not for your own systems.
CWE
CWE-129 Improper Validation of Array Index
OWASP Top 10
A05:2025 Injection
Published
Modified
Assigned by
zephyr (CNA)
NVD analysis
Awaiting analysis
Record from
the NVD, synced

Ask an AI about this CVE

Show the promptExplain CVE-2026-16664 for an engineer deciding whether to act. Use https://cve.bz/api/public/cves/CVE-2026-16664?via=ask-ai-copy and https://cve.bz/cve/CVE-2026-16664?via=ask-ai-copy as the source of truth: what is affected and which versions fix it, whether it is in CISA KEV, public exploits, and its EPSS (an internet-wide 30-day estimate of exploitation activity, not a forecast for my systems). If they give no fixed versions, use the CVE record https://cveawg.mitre.org/api/cve/CVE-2026-16664 or the vendor advisory, not third-party mirrors. Tell me how to check whether I am affected and how to verify a fix. Cite the sources and say where they are uncertain.

Opens a third-party assistant; its answer is its own, not cve.bz's. The prompt holds only this CVE's id and public links.

Badge for a README or a site

CVE-2026-16664

An image that stays current: it is drawn from the data each time it is fetched (a host that proxies images, as GitHub does, may show its copy for a while). Markdown:

[![CVE-2026-16664](https://cve.bz/cve/badge/CVE-2026-16664.svg)](https://cve.bz/cve/CVE-2026-16664)

HTML:

<a href="https://cve.bz/cve/CVE-2026-16664"><img src="https://cve.bz/cve/badge/CVE-2026-16664.svg" alt="CVE-2026-16664"></a>

Affected

Versions

From the CNA's record in the CVE List.

ProductAffected
mcu-tools mcuboot2.0.0 and later

Attack patterns (CAPEC)

  • CAPEC-100 Overflow Buffers Likelihood: High · Severity: Very High

The attack patterns MITRE's CAPEC relates to this record's weaknesses, as MITRE names them. Credits.

References

Check your stackJSON