{"id":"CVE-2026-16659","kind":"vulnerability","aliases":["CVE-2026-16659"],"related":[],"title":"MCUboot: malformed serial-recovery upload crashes bootloader via NULL flash pointer","description":"MCUboot's serial-recovery image-upload handler bs_upload() in boot/boot_serial/src/boot_serial.c declares const struct flash_area *fap = NULL and assigns it only via flash_area_open() part-way through the function. Two early validation failures (goto out_invalid_data) — a CBOR map that fails to decode, or an upload packet missing the off/data members — branch past the open while fap is still NULL, then fall into the shared epilogue. In MCUBOOT_ENC_IMAGES builds that epilogue unconditionally calls boot_handle_enc_fw(fap), which reaches boot_image_load_header() and flash_area_read() and dereferences the NULL flash_area.\n\nThe defect is reachable pre-authentication: the trigger is the very first serial-recovery upload command carrying a malformed payload. The guarding conditions are default-true on a fresh recovery session — img_num, curr_off and img_size are zero-initialized statics, so curr_off == img_size and the primary-slot test both hold. It requires a non-default build: encrypted images (MCUBOOT_ENC_IMAGES / Zephyr CONFIG_BOOT_ENCRYPT_IMAGE) together with an active serial-recovery transport, on the Zephyr or Mynewt port (the two that build both boot/boot_serial/src/boot_serial.c and boot_serial_encryption.c with MCUBOOT_ENC_IMAGES).\n\nThe impact is a transient denial of service of the bootloader during recovery. fap is a hard NULL rather than an attacker-controlled value, so there is no memory-corruption or information-leak primitive and image authentication is unaffected. Whether the dereference faults is platform-dependent — on targets where address 0x0 is mapped readable flash the read merely returns an error and execution continues, while targets that trap NULL (MPU / null-pointer-exception detection) take a hard fault. Because serial recovery is unauthenticated by design and already permits the console attacker to write the secondary slot, the added capability is only a low-value transient crash.\n\nThe related unconditional flash_area_close(fap) call in the same epilogue is a safe no-op on the ports that reach it, so it does not contribute to the dereference.\n\nThe affected ports are the Zephyr port — boot/zephyr/CMakeLists.txt compiles boot_serial.c under CONFIG_MCUBOOT_SERIAL and boot_serial_encryption.c under CONFIG_BOOT_ENCRYPT_IMAGE — and the Mynewt port, whose mcuboot_config.h defines MCUBOOT_SERIAL unconditionally and MCUBOOT_ENC_IMAGES under any BOOTUTIL_ENCRYPT_ syscfg, with boot/boot_serial/pkg.yml declaring no explicit source list so the whole directory is built. The Espressif port is not affected**: it compiles boot_serial.c but not boot_serial_encryption.c, and defines no MCUBOOT_ENC_IMAGES, so the #ifdef MCUBOOT_ENC_IMAGES block containing the call is preprocessed away. The NuttX, Cypress and Mbed ports do not build boot_serial.c at all.","summary":"MCUboot's serial-recovery upload handler dereferences a NULL flash area pointer when the first upload command has a malformed payload and encrypted-image support is enabled. An unauthenticated attacker on the serial console can trigger a transient bootloader crash, with no code execution or data disclosure.","severity":"medium","cvss":4.0,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["embedded","mcuboot","mynewt","runtime","zephyr"],"not_affected_if":["cypress-port","default-config","espressif-port","mbed-port","nuttx-port","serial-recovery-disabled"],"how_to_check":"- Check whether the build defines `MCUBOOT_ENC_IMAGES` (Zephyr `CONFIG_BOOT_ENCRYPT_IMAGE`, Mynewt any `BOOTUTIL_ENCRYPT_` syscfg) together with serial recovery (`MCUBOOT_SERIAL` / `CONFIG_MCUBOOT_SERIAL`).\n- Confirm the port is Zephyr or Mynewt; Espressif, NuttX, Cypress and Mbed are not affected.","fix":null,"status":"open","published_at":"2026-11-13T02:18:56+00:00","first_seen_at":"2026-11-13T02:41:37+00:00","triaged_at":"2026-11-13T02:43:04+00:00","updated_at":"2026-11-13T02:43:04+00:00","category":"runtime","confidence":0.7,"triage":{"at":"2026-11-13T02:43:04Z","model":"claude-haiku-5-5","output":{"fix":"- unknown","reach":"local","title":"MCUboot: malformed serial-recovery upload crashes bootloader via NULL flash pointer","impact":"low","summary":"MCUboot's serial-recovery upload handler dereferences a NULL flash area pointer when the first upload command has a malformed payload and encrypted-image support is enabled. An unauthenticated attacker on the serial console can trigger a transient bootloader crash, with no code execution or data disclosure.","audience":"developers","category":"runtime","nicknames":[],"who_cares":["mcuboot","zephyr","mynewt","embedded"],"confidence":0.7,"fix_status":"unknown","needs_auth":"no","worst_case":"bootloader crashes during recovery, transient denial of service only","analyst_note":"Confirm the fixed version and patch commit from the linked GitHub patch and vendor advisory; the sources here do not state one.","how_to_check":"- Check whether the build defines `MCUBOOT_ENC_IMAGES` (Zephyr `CONFIG_BOOT_ENCRYPT_IMAGE`, Mynewt any `BOOTUTIL_ENCRYPT_` syscfg) together with serial recovery (`MCUBOOT_SERIAL` / `CONFIG_MCUBOOT_SERIAL`).\n- Confirm the port is Zephyr or Mynewt; Espressif, NuttX, Cypress and Mbed are not affected.","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["default-config","espressif-port","nuttx-port","cypress-port","mbed-port","serial-recovery-disabled"],"who_is_affected":"Only builds of MCUboot on the Zephyr or Mynewt port that enable encrypted images together with an active serial-recovery transport are exposed. Devices using default configuration, other ports, or without serial recovery can skip it. The sources do not state a fixed version.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.00091,"input_tokens":5577,"output_tokens":704,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-16659':15A,18A '-2026':14A,17A '0x0':333C 'activ':254C 'add':381C 'address':332C 'affect':424C,485C 'alreadi':370C 'area':35B,90C,99C,167C,174C,395C 'assign':94C 'attack':55B,301C,374C 'attacker-control':300C 'authent':181C,318C 'away':513C 'block':507C 'boot':154C,161C,248C,272C,432C,439C,444C,488C,492C,523C 'boot/boot_serial/pkg.yml':468C 'boot/boot_serial/src/boot_serial.c':85C,270C 'boot/zephyr/cmakelists.txt':430C 'bootload':8A,64B,289C 'bootutil':464C 'branch':130C 'bs':82C 'build':149C,240C,268C,522C 'built':479C 'call':153C,398C,510C 'capabl':382C 'carri':193C 'cbor':116C 'close':396C 'code':68B 'command':41B,192C 'compil':431C,487C 'condit':199C 'config':247C,435C,443C 'config.h':453C 'consol':59B,373C 'const':87C 'contain':508C 'continu':346C 'contribut':419C 'control':302C 'corrupt':310C 'crash':7A,65B,390C 'curr':211C,222C 'cve':13A,16A 'cypress':516C 'data':71B,114C 'declar':86C,469C 'decod':121C 'default':202C,239C 'default-tru':201C 'defect':176C 'defin':454C,496C 'denial':284C 'depend':328C 'derefer':31B,170C,323C,422C 'design':368C 'detect':357C 'directori':477C 'disclosur':72B 'earli':108C 'embed':19B 'enabl':52B 'enc':147C,156C,244C,277C,460C,499C,505C 'encrypt':48B,241C,249C,445C,465C 'encrypted-imag':47B 'encryption.c':274C,441C,494C 'epilogu':144C,151C,402C 'error':343C 'espressif':481C 'except':356C 'execut':69B,345C 'explicit':471C 'fail':119C 'failur':110C 'fall':140C 'fap':91C,135C,158C,292C,397C 'fault':324C,361C 'first':39B,187C 'flash':11A,34B,89C,98C,166C,173C,337C,394C 'fresh':206C 'function':106C 'fw':157C 'goto':111C 'guard':198C 'handl':155C 'handler':30B,81C 'hard':295C,360C 'header':164C 'hold':233C 'ifdef':503C 'imag':49B,79C,148C,162C,242C,245C,250C,278C,317C,446C,461C,500C,506C 'image-upload':78C 'img':209C,214C,224C 'impact':280C 'inform':313C 'information-leak':312C 'initi':219C 'invalid':113C 'leak':314C 'list':473C 'load':163C 'low':387C 'low-valu':386C 'malform':2A,44B,195C 'map':117C,335C 'mbed':518C 'mcuboot':1A,20B,24B,73C,146C,243C,276C,436C,452C,455C,459C,498C,504C 'member':129C 'memori':309C 'memory-corrupt':308C 'mere':340C 'miss':126C 'mpu':352C 'mynewt':21B,263C,449C 'no-op':406C 'non':238C 'non-default':237C 'null':10A,33B,92C,138C,172C,296C,351C,354C 'null-pointer-except':353C 'num':210C 'nuttx':515C 'off/data':128C 'op':408C 'open':100C,133C 'packet':125C 'part':102C 'part-way':101C 'past':131C 'payload':45B,196C 'permit':371C 'platform':327C 'platform-depend':326C 'pointer':12A,36B,355C 'port':264C,411C,425C,429C,450C,482C,519C 'pre':180C 'pre-authent':179C 'preprocess':512C 'primari':229C 'primary-slot':228C 'primit':315C 'rather':297C 'reach':160C,413C 'reachabl':178C 'read':168C,339C 'readabl':336C 'recoveri':5A,28B,77C,190C,207C,257C,291C,364C 'relat':392C 'requir':235C 'return':341C 'runtim':22B 'safe':405C 'secondari':378C 'serial':4A,27B,58B,76C,189C,256C,273C,363C,437C,440C,456C,493C 'serial-recoveri':3A,26B,75C,188C,255C 'serial.c':433C,489C,524C 'servic':286C 'session':208C 'share':143C 'size':215C,225C 'slot':230C,379C 'sourc':472C 'static':220C 'still':137C 'struct':88C 'support':50B 'syscfg':466C 'take':358C 'target':330C,348C 'test':231C 'togeth':251C 'transient':63B,283C,389C 'transport':258C 'trap':350C 'trigger':61B,183C 'true':203C 'two':107C,266C 'unaffect':320C 'unauthent':54B,366C 'uncondit':152C,393C,457C 'upload':6A,29B,40B,80C,83C,124C,191C 'valid':109C 'valu':303C,388C 'via':9A,97C 'way':103C 'whether':321C 'whole':476C 'whose':451C 'write':376C 'zephyr':23B,246C,261C,428C 'zero':218C 'zero-initi':217C","nicknames":[],"mitigations":[],"who_affected":"Only builds of MCUboot on the Zephyr or Mynewt port that enable encrypted images together with an active serial-recovery transport are exposed. Devices using default configuration, other ports, or without serial recovery can skip it. The sources do not state a fixed version.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"none","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["embedded","mcuboot","medium","mynewt","runtime","zephyr"],"campaign_type":null,"search_a":"'-16659':15A,18A '-2026':14A,17A 'bootload':8A 'crash':7A 'cve':13A,16A 'flash':11A 'malform':2A 'mcuboot':1A 'null':10A 'pointer':12A 'recoveri':5A 'serial':4A 'serial-recoveri':3A 'upload':6A 'via':9A","search_b":"'area':35B 'attack':55B 'bootload':64B 'code':68B 'command':41B 'consol':59B 'crash':65B 'data':71B 'derefer':31B 'disclosur':72B 'embed':19B 'enabl':52B 'encrypt':48B 'encrypted-imag':47B 'execut':69B 'first':39B 'flash':34B 'handler':30B 'imag':49B 'malform':44B 'mcuboot':20B,24B 'mynewt':21B 'null':33B 'payload':45B 'pointer':36B 'recoveri':28B 'runtim':22B 'serial':27B,58B 'serial-recoveri':26B 'support':50B 'transient':63B 'trigger':61B 'unauthent':54B 'upload':29B,40B 'zephyr':23B","search_c":"'0x0':333C 'activ':254C 'add':381C 'address':332C 'affect':424C,485C 'alreadi':370C 'area':90C,99C,167C,174C,395C 'assign':94C 'attack':301C,374C 'attacker-control':300C 'authent':181C,318C 'away':513C 'block':507C 'boot':154C,161C,248C,272C,432C,439C,444C,488C,492C,523C 'boot/boot_serial/pkg.yml':468C 'boot/boot_serial/src/boot_serial.c':85C,270C 'boot/zephyr/cmakelists.txt':430C 'bootload':289C 'bootutil':464C 'branch':130C 'bs':82C 'build':149C,240C,268C,522C 'built':479C 'call':153C,398C,510C 'capabl':382C 'carri':193C 'cbor':116C 'close':396C 'command':192C 'compil':431C,487C 'condit':199C 'config':247C,435C,443C 'config.h':453C 'consol':373C 'const':87C 'contain':508C 'continu':346C 'contribut':419C 'control':302C 'corrupt':310C 'crash':390C 'curr':211C,222C 'cypress':516C 'data':114C 'declar':86C,469C 'decod':121C 'default':202C,239C 'default-tru':201C 'defect':176C 'defin':454C,496C 'denial':284C 'depend':328C 'derefer':170C,323C,422C 'design':368C 'detect':357C 'directori':477C 'earli':108C 'enc':147C,156C,244C,277C,460C,499C,505C 'encrypt':241C,249C,445C,465C 'encryption.c':274C,441C,494C 'epilogu':144C,151C,402C 'error':343C 'espressif':481C 'except':356C 'execut':345C 'explicit':471C 'fail':119C 'failur':110C 'fall':140C 'fap':91C,135C,158C,292C,397C 'fault':324C,361C 'first':187C 'flash':89C,98C,166C,173C,337C,394C 'fresh':206C 'function':106C 'fw':157C 'goto':111C 'guard':198C 'handl':155C 'handler':81C 'hard':295C,360C 'header':164C 'hold':233C 'ifdef':503C 'imag':79C,148C,162C,242C,245C,250C,278C,317C,446C,461C,500C,506C 'image-upload':78C 'img':209C,214C,224C 'impact':280C 'inform':313C 'information-leak':312C 'initi':219C 'invalid':113C 'leak':314C 'list':473C 'load':163C 'low':387C 'low-valu':386C 'malform':195C 'map':117C,335C 'mbed':518C 'mcuboot':73C,146C,243C,276C,436C,452C,455C,459C,498C,504C 'member':129C 'memori':309C 'memory-corrupt':308C 'mere':340C 'miss':126C 'mpu':352C 'mynewt':263C,449C 'no-op':406C 'non':238C 'non-default':237C 'null':92C,138C,172C,296C,351C,354C 'null-pointer-except':353C 'num':210C 'nuttx':515C 'off/data':128C 'op':408C 'open':100C,133C 'packet':125C 'part':102C 'part-way':101C 'past':131C 'payload':196C 'permit':371C 'platform':327C 'platform-depend':326C 'pointer':355C 'port':264C,411C,425C,429C,450C,482C,519C 'pre':180C 'pre-authent':179C 'preprocess':512C 'primari':229C 'primary-slot':228C 'primit':315C 'rather':297C 'reach':160C,413C 'reachabl':178C 'read':168C,339C 'readabl':336C 'recoveri':77C,190C,207C,257C,291C,364C 'relat':392C 'requir':235C 'return':341C 'safe':405C 'secondari':378C 'serial':76C,189C,256C,273C,363C,437C,440C,456C,493C 'serial-recoveri':75C,188C,255C 'serial.c':433C,489C,524C 'servic':286C 'session':208C 'share':143C 'size':215C,225C 'slot':230C,379C 'sourc':472C 'static':220C 'still':137C 'struct':88C 'syscfg':466C 'take':358C 'target':330C,348C 'test':231C 'togeth':251C 'transient':283C,389C 'transport':258C 'trap':350C 'trigger':183C 'true':203C 'two':107C,266C 'unaffect':320C 'unauthent':366C 'uncondit':152C,393C,457C 'upload':80C,83C,124C,191C 'valid':109C 'valu':303C,388C 'via':97C 'way':103C 'whether':321C 'whole':476C 'whose':451C 'write':376C 'zephyr':246C,261C,428C 'zero':218C 'zero-initi':217C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-12T23:24:40+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_by":"vulnerabilities@zephyrproject.org","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-16659","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-16659","severity":null,"published_at":"2026-11-13T02:18:56+00:00","modified_at":"2026-11-13T02:18:56+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":141885,"url":"https://github.com/mcu-tools/mcuboot/commit/400f9a7242641655948b08acac19932f56d9881f","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":141886,"url":"https://github.com/mcu-tools/mcuboot/security/advisories/GHSA-777r-3chm-p78c","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-12T23:24:40+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"}