{"id":"CVE-2026-16664","kind":"vulnerability","aliases":["CVE-2026-16664"],"related":[],"title":"MCUboot: serial recovery upload reads out of bounds, crashing the bootloader","description":"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.\n\nThe 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).\n\nflash_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 0xFFFFFFFF converts to -1 and reads all_slots[-2], off the front of the table, while large positive values read off the end (CWE-192). 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.\nThis 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.","summary":"MCUboot's Zephyr serial recovery handler accepts an unchecked image index in MCUmgr upload requests, which indexes past a flash slot table. An attacker with access to the unauthenticated serial recovery console can crash the bootloader, and in rare cases write to a partition outside the image set.","severity":"medium","cvss":5.1,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["embedded","firmware","mcuboot","runtime","zephyr"],"not_affected_if":["direct-image-upload","no-serial-recovery","single-application-slot"],"how_to_check":"- Check whether the device runs MCUboot on Zephyr with serial recovery enabled and `MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD` disabled\n- Check the MCUboot version in use against the fixed versions in the product data","fix":null,"status":"open","published_at":"2026-11-13T02:18:57+00:00","first_seen_at":"2026-11-13T02:41:37+00:00","triaged_at":"2026-11-13T02:43:02+00:00","updated_at":"2026-11-13T02:43:02+00:00","category":"runtime","confidence":0.8,"triage":{"at":"2026-11-13T02:43:02Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"local","title":"MCUboot: serial recovery upload reads out of bounds, crashing the bootloader","impact":"medium","summary":"MCUboot's Zephyr serial recovery handler accepts an unchecked image index in MCUmgr upload requests, which indexes past a flash slot table. An attacker with access to the unauthenticated serial recovery console can crash the bootloader, and in rare cases write to a partition outside the image set.","audience":"developers","category":"runtime","nicknames":[],"who_cares":["mcuboot","zephyr","embedded","firmware"],"confidence":0.8,"fix_status":"unknown","needs_auth":"no","worst_case":"bootloader crashes during recovery; rare out-of-bounds flash erase or write","analyst_note":"Confirm fixed MCUboot versions and the vendor advisory text, since the sources give no fixed version or fix status.","how_to_check":"- Check whether the device runs MCUboot on Zephyr with serial recovery enabled and `MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD` disabled\n- Check the MCUboot version in use against the fixed versions in the product data\n- unknown for any further product-specific check","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["direct-image-upload","single-application-slot","no-serial-recovery"],"who_is_affected":"Devices that boot with MCUboot on Zephyr and expose the serial/SMP recovery console, using the default non-direct upload path and the array-backed slot layout (not CONFIG_SINGLE_APPLICATION_SLOT). The issue applies even to default single-image builds for image numbers of 1 or higher. Devices without a reachable serial recovery console, or using direct image upload, are not affected.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.00089,"input_tokens":5600,"output_tokens":660,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-06':542C '-07':551C '-1':342C '-16664':14A,17A '-19':552C '-192':363C '-2':347C '-2026':13A,16A '-22':543C '-787':453C '0':111C,133C,482C '0xffffffff':339C '1':266C,280C '2':162C,170C,370C '2026':541C,550C '32':102C '88p6':557C '8v33':556C 'accept':29B 'access':48B,193C 'adjac':404C 'advisori':567C 'affect':276C 'anyon':191C 'appli':501C 'applic':249C 'area':125C,142C,292C,304C,411C,418C,515C 'argument':525C 'array':242C 'array-back':241C 'attack':46B,324C,456C 'attacker-suppli':455C 'back':243C,462C 'bad':207C 'bit':103C 'boot':476C 'boot/boot_serial/src/boot_serial.c':82C 'boot/zephyr/include/sysflash/sysflash.h':147C 'bootload':11A,58B,391C 'bound':8A,184C,521C 'bounds-check':520C 'bs':79C 'build':274C 'bus/hard':381C 'case':62B,512C 'check':116C,522C 'close':561C 'comparison':489C 'config':247C 'configur':260C 'consol':54B,199C 'const':152C 'control':325C 'convers':504C 'convert':340C 'crash':9A,56B 'cve':12A,15A 'cwe':362C,452C 'decod':83C 'default':223C,264C,270C 'defect':218C 'defenc':527C 'denial':386C 'depth':529C 'design':204C 'direct':226C,231C,284C,295C 'disabl':234C 'disclosur':468C 'duplic':564C 'echo':461C 'einval':299C,426C 'either':364C 'embed':18B 'end':361C 'entri':171C 'equival':499C 'erase/write':443C 'err':425C 'even':268C 'fail':422C 'fault':382C 'field':89C 'firmwar':19B 'fix':470C 'flash':42B,124C,141C,291C,303C,410C,417C,514C 'flash-area':409C 'front':350C 'full':101C,574C 'garbag':408C,430C 'gate':254C 'ghsa':555C 'ghsa-8v33-88p6-jffj':554C 'give':383C 'guard':500C 'hand':415C 'handler':28B,78C 'happen':432C 'hold':165C 'host':86C 'host-suppli':85C 'id':126C,143C,293C,305C,412C,431C,516C 'imag':32B,69B,88C,94C,129C,168C,177C,213C,232C,259C,262C,273C,279C,285C,296C,308C,314C,337C,439C,450C,477C 'image-upload':93C 'img':98C,120C,131C,160C,174C,317C,369C,474C,496C 'independ':534C 'index':33B,39B,149C,315C,330C,367C 'indic':302C,400C 'inform':467C 'int':153C,313C,374C,506C 'jffj':558C 'kai':546C 'kaimandal':548C 'larg':355C 'latch':106C 'layout':245C 'lookup':487C 'made':492C 'magnitud':335C 'match':434C 'mcuboot':1A,20B,23B,71C,167C,176C,229C,261C,282C 'mcumgr':35B,92C 'mgmt':424C 'moder':395C 'multi':128C,258C,307C 'multi-imag':257C 'multipli':368C 'must':490C 'negat':511C 'never':460C 'non':225C,438C 'non-direct':224C 'non-imag':437C 'normal':421C 'num':99C,121C,132C,161C,175C,318C,475C,497C 'number':169C,178C,263C,478C 'nvidia':537C 'offset':378C 'open':419C 'origin':569C 'out-of-bound':181C 'out-of-rang':396C 'outsid':67B,448C 'packet':112C,483C 'partit':66B,440C,447C 'pass':119C 'past':40B 'path':187C,228C,287C 'perform':372C 'phan':547C 'port':138C,238C 'posit':356C 'project':538C 'rang':115C,399C 'rare':61B 'reachabl':189C 'read':5A,185C,344C,358C,402C 'recoveri':3A,27B,53B,76C,198C,393C 'reject':473C,509C 'reliabl':385C 'report':533C,570C 'reproduc':572C 'request':37B,96C 'resolv':139C 'return':298C,403C 'rodata':405C 'runtim':21B 'safe':289C 'serial':2A,26B,52B,75C,196C,230C,283C 'serial-recoveri':74C 'servic':388C 'set':70B,451C 'sign':312C,327C 'signatur':214C 'singl':248C,272C 'single-imag':271C 'slot':43B,130C,145C,155C,159C,244C,250C,309C,346C,486C,518C 'smp':197C 'specif':220C 'static':151C 'straight':122C 'subsequ':442C 'suppli':87C,210C,457C 'switch':297C 'tabl':44B,156C,164C,353C 'take':310C 'target':445C 'twice':535C 'uint32':320C 'unauthent':51B,202C 'uncheck':31B 'unknown':301C 'unsign':495C 'upload':4A,36B,77C,80C,95C,227C,233C,286C 'valid':436C 'valu':104C,208C,357C,458C 'vanessa':539C 'verifi':216C 'vulner':531C 'way':365C 'well':332C 'wild':377C 'without':113C 'would':507C 'write':63B 'yield':379C 'zephyr':22B,25B,73C,137C,237C","nicknames":[],"mitigations":[],"who_affected":"Devices that boot with MCUboot on Zephyr and expose the serial/SMP recovery console, using the default non-direct upload path and the array-backed slot layout (not CONFIG_SINGLE_APPLICATION_SLOT). The issue applies even to default single-image builds for image numbers of 1 or higher. Devices without a reachable serial recovery console, or using direct image upload, are not affected.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"unknown","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["embedded","firmware","mcuboot","medium","runtime","zephyr"],"campaign_type":null,"search_a":"'-16664':14A,17A '-2026':13A,16A 'bootload':11A 'bound':8A 'crash':9A 'cve':12A,15A 'mcuboot':1A 'read':5A 'recoveri':3A 'serial':2A 'upload':4A","search_b":"'accept':29B 'access':48B 'attack':46B 'bootload':58B 'case':62B 'consol':54B 'crash':56B 'embed':18B 'firmwar':19B 'flash':42B 'handler':28B 'imag':32B,69B 'index':33B,39B 'mcuboot':20B,23B 'mcumgr':35B 'outsid':67B 'partit':66B 'past':40B 'rare':61B 'recoveri':27B,53B 'request':37B 'runtim':21B 'serial':26B,52B 'set':70B 'slot':43B 'tabl':44B 'unauthent':51B 'uncheck':31B 'upload':36B 'write':63B 'zephyr':22B,25B","search_c":"'-06':542C '-07':551C '-1':342C '-19':552C '-192':363C '-2':347C '-22':543C '-787':453C '0':111C,133C,482C '0xffffffff':339C '1':266C,280C '2':162C,170C,370C '2026':541C,550C '32':102C '88p6':557C '8v33':556C 'access':193C 'adjac':404C 'advisori':567C 'affect':276C 'anyon':191C 'appli':501C 'applic':249C 'area':125C,142C,292C,304C,411C,418C,515C 'argument':525C 'array':242C 'array-back':241C 'attack':324C,456C 'attacker-suppli':455C 'back':243C,462C 'bad':207C 'bit':103C 'boot':476C 'boot/boot_serial/src/boot_serial.c':82C 'boot/zephyr/include/sysflash/sysflash.h':147C 'bootload':391C 'bound':184C,521C 'bounds-check':520C 'bs':79C 'build':274C 'bus/hard':381C 'case':512C 'check':116C,522C 'close':561C 'comparison':489C 'config':247C 'configur':260C 'consol':199C 'const':152C 'control':325C 'convers':504C 'convert':340C 'cwe':362C,452C 'decod':83C 'default':223C,264C,270C 'defect':218C 'defenc':527C 'denial':386C 'depth':529C 'design':204C 'direct':226C,231C,284C,295C 'disabl':234C 'disclosur':468C 'duplic':564C 'echo':461C 'einval':299C,426C 'either':364C 'end':361C 'entri':171C 'equival':499C 'erase/write':443C 'err':425C 'even':268C 'fail':422C 'fault':382C 'field':89C 'fix':470C 'flash':124C,141C,291C,303C,410C,417C,514C 'flash-area':409C 'front':350C 'full':101C,574C 'garbag':408C,430C 'gate':254C 'ghsa':555C 'ghsa-8v33-88p6-jffj':554C 'give':383C 'guard':500C 'hand':415C 'handler':78C 'happen':432C 'hold':165C 'host':86C 'host-suppli':85C 'id':126C,143C,293C,305C,412C,431C,516C 'imag':88C,94C,129C,168C,177C,213C,232C,259C,262C,273C,279C,285C,296C,308C,314C,337C,439C,450C,477C 'image-upload':93C 'img':98C,120C,131C,160C,174C,317C,369C,474C,496C 'independ':534C 'index':149C,315C,330C,367C 'indic':302C,400C 'inform':467C 'int':153C,313C,374C,506C 'jffj':558C 'kai':546C 'kaimandal':548C 'larg':355C 'latch':106C 'layout':245C 'lookup':487C 'made':492C 'magnitud':335C 'match':434C 'mcuboot':71C,167C,176C,229C,261C,282C 'mcumgr':92C 'mgmt':424C 'moder':395C 'multi':128C,258C,307C 'multi-imag':257C 'multipli':368C 'must':490C 'negat':511C 'never':460C 'non':225C,438C 'non-direct':224C 'non-imag':437C 'normal':421C 'num':99C,121C,132C,161C,175C,318C,475C,497C 'number':169C,178C,263C,478C 'nvidia':537C 'offset':378C 'open':419C 'origin':569C 'out-of-bound':181C 'out-of-rang':396C 'outsid':448C 'packet':112C,483C 'partit':440C,447C 'pass':119C 'path':187C,228C,287C 'perform':372C 'phan':547C 'port':138C,238C 'posit':356C 'project':538C 'rang':115C,399C 'reachabl':189C 'read':185C,344C,358C,402C 'recoveri':76C,198C,393C 'reject':473C,509C 'reliabl':385C 'report':533C,570C 'reproduc':572C 'request':96C 'resolv':139C 'return':298C,403C 'rodata':405C 'safe':289C 'serial':75C,196C,230C,283C 'serial-recoveri':74C 'servic':388C 'set':451C 'sign':312C,327C 'signatur':214C 'singl':248C,272C 'single-imag':271C 'slot':130C,145C,155C,159C,244C,250C,309C,346C,486C,518C 'smp':197C 'specif':220C 'static':151C 'straight':122C 'subsequ':442C 'suppli':87C,210C,457C 'switch':297C 'tabl':156C,164C,353C 'take':310C 'target':445C 'twice':535C 'uint32':320C 'unauthent':202C 'unknown':301C 'unsign':495C 'upload':77C,80C,95C,227C,233C,286C 'valid':436C 'valu':104C,208C,357C,458C 'vanessa':539C 'verifi':216C 'vulner':531C 'way':365C 'well':332C 'wild':377C 'without':113C 'would':507C 'yield':379C 'zephyr':73C,137C,237C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-12T23:51:24+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L","cvss_by":"vulnerabilities@zephyrproject.org","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-16664","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-16664","severity":null,"published_at":"2026-11-13T02:18:57+00:00","modified_at":"2026-11-13T02:18:57+00:00","first_seen_at":"2026-11-13T02:41:37+00:00","fetched_at":"2026-11-13T02:41:37+00:00","note":null}],"documents":[{"id":141889,"url":"https://github.com/mcu-tools/mcuboot/commit/183a05f256bdbbac86edcb048958da59018f814e","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":141890,"url":"https://github.com/mcu-tools/mcuboot/security/advisories/GHSA-8rcq-2mgr-fhp8","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-12T23:51:24+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}