{"id":"CVE-2026-16662","kind":"vulnerability","aliases":["CVE-2026-16662"],"related":[],"title":"MCUboot: short image hash leaks bootloader stack into measured-boot record","description":"boot_save_boot_status() in boot/bootutil/src/boot_record.c reads the image's EXPECTED_HASH_TLV into a stack buffer image_hash[IMAGE_HASH_SIZE] that is never zero-initialised. The TLV handler validates only the upper bound (len > sizeof(image_hash)) and then reads exactly len bytes, so a TLV shorter than IMAGE_HASH_SIZE leaves the tail of image_hash holding stale stack content. The subsequent copy into the boot record, memcpy(buf + offset, image_hash, sizeof(image_hash)), uses the fixed buffer size rather than len, so up to IMAGE_HASH_SIZE - 1 bytes of uninitialised bootloader stack are written into the measured-boot record.\n\nThe defect is reachable only under MCUBOOT_MEASURED_BOOT, and only when the image reaching boot_save_boot_status() was not hash-validated on that boot. bootutil_img_validate() rejects a hash TLV whose length is not exactly sizeof(hash) (boot/bootutil/src/image_validate.c:345), and primary-slot validation is on by default (Zephyr's CONFIG_BOOT_VALIDATE_SLOT0 defaults to y), so in a default build the malformed image never reaches this code. The direct-XIP and RAM-load strategies in boot/bootutil/src/loader.c validate the selected slot unconditionally and are not affected. The short TLV survives only where the integrator has turned primary-slot validation off: the swap and overwrite loader built without MCUBOOT_VALIDATE_PRIMARY_SLOT, which checks only the image magic before calling boot_add_shared_data(), and the Zephyr single-slot loader (boot/zephyr/single_loader.c) built without it, including the MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE variant, which skips validation once the trailer records an earlier successful one. It is also reachable through a time-of-check/time-of-use change to tamperable external flash between validation and the boot-record read. Placing the crafted image requires physical or flash-write access to the device; in a single-slot build with serial recovery enabled, the serial-recovery upload writes the primary slot directly and can place it as well.\n\nIn these configurations the boot record's measurement is already not trustworthy: with validation off, the hash copied into the record is the image's own unverified EXPECTED_HASH_TLV, which the attacker chooses. The defect therefore does not weaken attestation integrity any further. What it adds is a path for bootloader memory to leave the device: up to 63 bytes (IMAGE_HASH_SIZE - 1) of uninitialised bootloader stack are embedded in the measurement field that a downstream attestation service sends to a remote verifier. In the configurations analysed the residue is bootloader internal state (TLV offsets and lengths, flash addresses, loop state), not key material, but what occupies that stack region depends on configuration and on which code ran before boot_save_boot_status(). It is reported as a low-severity, defense-in-depth disclosure with no integrity or availability impact.\n\nThis is distinct from the already-fixed record_len integer underflow in the same routine (GHSA-8hrv-4cp5-4rg3). The fix rejects any EXPECTED_HASH_TLV whose length is not exactly IMAGE_HASH_SIZE.","summary":"MCUboot's measured-boot record copies a fixed-size stack buffer for the image hash, so a hash TLV shorter than expected leaves uninitialised bootloader stack bytes in the record. An attacker with flash-write access can embed up to 63 bytes of bootloader stack residue in the attestation measurement sent to a remote verifier.","severity":"low","cvss":2.4,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["embedded","mcuboot","measured-boot","runtime","zephyr"],"not_affected_if":["default-config","direct-xip-or-ram-load","managed-hosting"],"how_to_check":"- Check whether the build defines `MCUBOOT_MEASURED_BOOT` and whether primary-slot validation is disabled (`MCUBOOT_VALIDATE_PRIMARY_SLOT` absent, or Zephyr `CONFIG_BOOT_VALIDATE_SLOT0` set to `n`)\n- Check whether the single-slot Zephyr loader is used with `MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE`","fix":"- Move to the release containing the fix that rejects EXPECTED_HASH_TLV whose length is not exactly IMAGE_HASH_SIZE (version unknown from the sources)","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:09+00:00","updated_at":"2026-11-13T02:43:09+00:00","category":"runtime","confidence":0.7,"triage":{"at":"2026-11-13T02:43:09Z","model":"claude-haiku-5-5","output":{"fix":"- Move to the release containing the fix that rejects EXPECTED_HASH_TLV whose length is not exactly IMAGE_HASH_SIZE (version unknown from the sources)","reach":"local","title":"MCUboot: short image hash leaks bootloader stack into measured-boot record","impact":"low","summary":"MCUboot's measured-boot record copies a fixed-size stack buffer for the image hash, so a hash TLV shorter than expected leaves uninitialised bootloader stack bytes in the record. An attacker with flash-write access can embed up to 63 bytes of bootloader stack residue in the attestation measurement sent to a remote verifier.","audience":"businesses","category":"runtime","nicknames":[],"who_cares":["mcuboot","zephyr","measured-boot","embedded"],"confidence":0.7,"fix_status":"available","needs_auth":"yes","worst_case":"Bootloader stack residue leaks in attestation measurement","analyst_note":"","how_to_check":"- Check whether the build defines `MCUBOOT_MEASURED_BOOT` and whether primary-slot validation is disabled (`MCUBOOT_VALIDATE_PRIMARY_SLOT` absent, or Zephyr `CONFIG_BOOT_VALIDATE_SLOT0` set to `n`)\n- Check whether the single-slot Zephyr loader is used with `MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE`","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["default-config","direct-xip-or-ram-load","managed-hosting"],"who_is_affected":"Only devices running MCUboot with measured boot enabled and primary-slot validation turned off, such as swap/overwrite loaders built without MCUBOOT_VALIDATE_PRIMARY_SLOT or single-slot Zephyr builds without validation. Default builds validate the image before this code runs and are not affected. Exploitation requires physical or flash-write access to the device.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000932,"input_tokens":5648,"output_tokens":735,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-16662':15A,18A '-2026':14A,17A '/time-of-use':362C '1':177C,480C '345':233C '4cp5':579C '4rg3':580C '63':69B,475C '8hrv':578C 'access':64B,386C 'add':319C,462C 'address':516C 'affect':283C 'alreadi':425C,566C 'already-fix':565C 'also':354C 'analys':504C 'attack':59B,448C 'attest':77B,456C,494C 'avail':558C 'boot':11A,23B,30B,84C,86C,153C,189C,199C,206C,208C,217C,246C,318C,373C,420C,537C,539C 'boot-record':372C 'boot/bootutil/src/boot_record.c':89C 'boot/bootutil/src/image_validate.c':232C 'boot/bootutil/src/loader.c':274C 'boot/zephyr/single_loader.c':329C 'bootload':6A,52B,72B,181C,467C,483C,508C 'bootutil':218C 'bound':119C 'buf':156C 'buffer':38B,100C,166C 'build':256C,395C 'built':304C,330C 'byte':54B,70B,129C,178C,476C 'call':317C 'chang':363C 'check':311C,361C 'choos':449C 'code':263C,534C 'config':245C 'configur':418C,503C,530C 'content':147C 'copi':32B,150C,433C 'craft':378C 'cve':13A,16A 'data':321C 'default':242C,249C,255C 'defect':192C,451C 'defens':550C 'defense-in-depth':549C 'depend':528C 'depth':552C 'devic':389C,472C 'direct':266C,409C 'direct-xip':265C 'disclosur':553C 'distinct':562C 'downstream':493C 'earlier':349C 'emb':66B 'embed':19B,486C 'enabl':399C 'exact':127C,229C,592C 'expect':49B,94C,443C,585C 'extern':366C 'field':490C 'fix':35B,165C,567C,582C 'fixed-s':34B 'flash':62B,367C,384C,515C 'flash-writ':61B,383C 'ghsa':577C 'ghsa-8hrv-4cp5-4rg3':576C 'handler':114C 'hash':4A,42B,45B,95C,102C,104C,123C,136C,143C,159C,162C,175C,213C,223C,231C,432C,444C,478C,586C,594C 'hash-valid':212C 'hold':144C 'imag':3A,41B,92C,101C,103C,122C,135C,142C,158C,161C,174C,204C,259C,314C,379C,439C,477C,593C 'img':219C 'impact':559C 'includ':333C 'initialis':111C 'integ':570C 'integr':291C,457C,556C 'intern':509C 'key':520C 'leak':5A 'leav':50B,138C,470C 'len':120C,128C,170C,569C 'length':226C,514C,589C 'load':271C 'loader':303C,328C 'loop':517C 'low':547C 'low-sever':546C 'magic':315C 'malform':258C 'materi':521C 'mcuboot':1A,20B,26B,197C,306C,335C 'measur':10A,22B,29B,78B,188C,198C,423C,489C 'measured-boot':9A,21B,28B,187C 'memcpi':155C 'memori':468C 'never':108C,260C 'occupi':524C 'offset':157C,512C 'one':351C 'overwrit':302C 'path':465C 'physic':381C 'place':376C,412C 'primari':236C,295C,308C,337C,407C 'primary-slot':235C,294C 'ram':270C 'ram-load':269C 'ran':535C 'rather':168C 'reach':205C,261C 'reachabl':194C,355C 'read':90C,126C,375C 'record':12A,31B,57B,154C,190C,347C,374C,421C,436C,568C 'recoveri':398C,403C 'region':527C 'reject':221C,583C 'remot':82B,499C 'report':543C 'requir':380C 'residu':74B,506C 'routin':575C 'runtim':24B 'save':85C,207C,538C 'select':277C 'send':496C 'sent':79B 'serial':397C,402C 'serial-recoveri':401C 'servic':495C 'sever':548C 'share':320C 'short':2A,285C 'shorter':47B,133C 'singl':326C,393C 'single-slot':325C,392C 'size':36B,105C,137C,167C,176C,479C,595C 'sizeof':121C,160C,230C 'skip':342C 'slot':237C,278C,296C,309C,327C,338C,394C,408C 'slot0':248C 'stack':7A,37B,53B,73B,99C,146C,182C,484C,526C 'stale':145C 'state':510C,518C 'status':87C,209C,540C 'strategi':272C 'subsequ':149C 'success':350C 'surviv':287C 'swap':300C 'tail':140C 'tamper':365C 'therefor':452C 'time':359C 'time-of-check':358C 'tlv':46B,96C,113C,132C,224C,286C,445C,511C,587C 'trailer':346C 'trustworthi':427C 'turn':293C 'uncondit':279C 'underflow':571C 'uninitialis':51B,180C,482C 'unverifi':442C 'upload':404C 'upper':118C 'use':163C 'valid':115C,214C,220C,238C,247C,275C,297C,307C,336C,343C,369C,429C 'variant':340C 'verifi':83B,500C 'weaken':455C 'well':415C 'whose':225C,588C 'without':305C,331C 'write':63B,385C,405C 'written':184C 'xip':267C 'y':251C 'zephyr':25B,243C,324C 'zero':110C 'zero-initialis':109C","nicknames":[],"mitigations":[],"who_affected":"Only devices running MCUboot with measured boot enabled and primary-slot validation turned off, such as swap/overwrite loaders built without MCUBOOT_VALIDATE_PRIMARY_SLOT or single-slot Zephyr builds without validation. Default builds validate the image before this code runs and are not affected. Exploitation requires physical or flash-write access to the device.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":[],"ptokens":[],"labels":["embedded","low","mcuboot","measuredboot","runtime","zephyr"],"campaign_type":null,"search_a":"'-16662':15A,18A '-2026':14A,17A 'boot':11A 'bootload':6A 'cve':13A,16A 'hash':4A 'imag':3A 'leak':5A 'mcuboot':1A 'measur':10A 'measured-boot':9A 'record':12A 'short':2A 'stack':7A","search_b":"'63':69B 'access':64B 'attack':59B 'attest':77B 'boot':23B,30B 'bootload':52B,72B 'buffer':38B 'byte':54B,70B 'copi':32B 'emb':66B 'embed':19B 'expect':49B 'fix':35B 'fixed-s':34B 'flash':62B 'flash-writ':61B 'hash':42B,45B 'imag':41B 'leav':50B 'mcuboot':20B,26B 'measur':22B,29B,78B 'measured-boot':21B,28B 'record':31B,57B 'remot':82B 'residu':74B 'runtim':24B 'sent':79B 'shorter':47B 'size':36B 'stack':37B,53B,73B 'tlv':46B 'uninitialis':51B 'verifi':83B 'write':63B 'zephyr':25B","search_c":"'/time-of-use':362C '1':177C,480C '345':233C '4cp5':579C '4rg3':580C '63':475C '8hrv':578C 'access':386C 'add':319C,462C 'address':516C 'affect':283C 'alreadi':425C,566C 'already-fix':565C 'also':354C 'analys':504C 'attack':448C 'attest':456C,494C 'avail':558C 'boot':84C,86C,153C,189C,199C,206C,208C,217C,246C,318C,373C,420C,537C,539C 'boot-record':372C 'boot/bootutil/src/boot_record.c':89C 'boot/bootutil/src/image_validate.c':232C 'boot/bootutil/src/loader.c':274C 'boot/zephyr/single_loader.c':329C 'bootload':181C,467C,483C,508C 'bootutil':218C 'bound':119C 'buf':156C 'buffer':100C,166C 'build':256C,395C 'built':304C,330C 'byte':129C,178C,476C 'call':317C 'chang':363C 'check':311C,361C 'choos':449C 'code':263C,534C 'config':245C 'configur':418C,503C,530C 'content':147C 'copi':150C,433C 'craft':378C 'data':321C 'default':242C,249C,255C 'defect':192C,451C 'defens':550C 'defense-in-depth':549C 'depend':528C 'depth':552C 'devic':389C,472C 'direct':266C,409C 'direct-xip':265C 'disclosur':553C 'distinct':562C 'downstream':493C 'earlier':349C 'embed':486C 'enabl':399C 'exact':127C,229C,592C 'expect':94C,443C,585C 'extern':366C 'field':490C 'fix':165C,567C,582C 'flash':367C,384C,515C 'flash-writ':383C 'ghsa':577C 'ghsa-8hrv-4cp5-4rg3':576C 'handler':114C 'hash':95C,102C,104C,123C,136C,143C,159C,162C,175C,213C,223C,231C,432C,444C,478C,586C,594C 'hash-valid':212C 'hold':144C 'imag':92C,101C,103C,122C,135C,142C,158C,161C,174C,204C,259C,314C,379C,439C,477C,593C 'img':219C 'impact':559C 'includ':333C 'initialis':111C 'integ':570C 'integr':291C,457C,556C 'intern':509C 'key':520C 'leav':138C,470C 'len':120C,128C,170C,569C 'length':226C,514C,589C 'load':271C 'loader':303C,328C 'loop':517C 'low':547C 'low-sever':546C 'magic':315C 'malform':258C 'materi':521C 'mcuboot':197C,306C,335C 'measur':188C,198C,423C,489C 'measured-boot':187C 'memcpi':155C 'memori':468C 'never':108C,260C 'occupi':524C 'offset':157C,512C 'one':351C 'overwrit':302C 'path':465C 'physic':381C 'place':376C,412C 'primari':236C,295C,308C,337C,407C 'primary-slot':235C,294C 'ram':270C 'ram-load':269C 'ran':535C 'rather':168C 'reach':205C,261C 'reachabl':194C,355C 'read':90C,126C,375C 'record':154C,190C,347C,374C,421C,436C,568C 'recoveri':398C,403C 'region':527C 'reject':221C,583C 'remot':499C 'report':543C 'requir':380C 'residu':506C 'routin':575C 'save':85C,207C,538C 'select':277C 'send':496C 'serial':397C,402C 'serial-recoveri':401C 'servic':495C 'sever':548C 'share':320C 'short':285C 'shorter':133C 'singl':326C,393C 'single-slot':325C,392C 'size':105C,137C,167C,176C,479C,595C 'sizeof':121C,160C,230C 'skip':342C 'slot':237C,278C,296C,309C,327C,338C,394C,408C 'slot0':248C 'stack':99C,146C,182C,484C,526C 'stale':145C 'state':510C,518C 'status':87C,209C,540C 'strategi':272C 'subsequ':149C 'success':350C 'surviv':287C 'swap':300C 'tail':140C 'tamper':365C 'therefor':452C 'time':359C 'time-of-check':358C 'tlv':96C,113C,132C,224C,286C,445C,511C,587C 'trailer':346C 'trustworthi':427C 'turn':293C 'uncondit':279C 'underflow':571C 'uninitialis':180C,482C 'unverifi':442C 'upload':404C 'upper':118C 'use':163C 'valid':115C,214C,220C,238C,247C,275C,297C,307C,336C,343C,369C,429C 'variant':340C 'verifi':500C 'weaken':455C 'well':415C 'whose':225C,588C 'without':305C,331C 'write':385C,405C 'written':184C 'xip':267C 'y':251C 'zephyr':243C,324C 'zero':110C 'zero-initialis':109C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-12T23:12:24+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N","cvss_by":"vulnerabilities@zephyrproject.org","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-16662","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-16662","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":141887,"url":"https://github.com/mcu-tools/mcuboot/commit/5098d8eef1139abd3d821d8138a6321d656dcd3e","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":141888,"url":"https://github.com/mcu-tools/mcuboot/security/advisories/GHSA-779w-4x76-5chf","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-12T23:12: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"}