{"id":"CVE-2026-127915","kind":"vulnerability","aliases":["CVE-2026-127915"],"related":[],"title":"MCUboot: TLV iterator can read past trailer area during image validation","description":"The MCUboot TLV iterator bootutil_tlv_iter_next() in boot/bootutil/src/tlv.c walks image trailer TLVs with a single loop guard (it->tlv_off < it->tlv_end) and advances by sizeof(struct image_tlv) + tlv.it_len using the attacker-controlled it_len field, without validating that the entry's header or payload stays within it->tlv_end. As a result the 4-byte header read can extend up to 3 bytes past the declared TLV area, and the returned (off, len) can describe a payload that runs past it.\n\nThe path is pre-authentication: TLVs are parsed during bootutil_img_validate() before the signature is verified, and a crafted image can be presented through DFU / serial-recovery / OTA. However the impact is contained by surrounding guards: bootutil_img_validate() first rejects a TLV area larger than bootutil_max_image_size(), the default LOAD_IMAGE_DATA sink is flash_area_read() which bounds-checks against the flash partition and fails an out-of-partition read, and every payload consumer (EXPECTED_HASH_TLV, EXPECTED_KEY_TLV, EXPECTED_SIG_TLV, IMAGE_TLV_SEC_CNT) clamps len against a fixed buffer before copying.\n\nThe residual effect in a default flash build is therefore an out-of-region read confined to the attacker's own slot partition whose result is never observable, yielding at worst a clean validation failure rather than memory corruption or information disclosure. A genuine (though still bounded) out-of-bounds read remains under the non-default MCUBOOT_RAM_LOAD configuration, where LOAD_IMAGE_DATA is an unchecked memcpy. The fix is to validate each entry's header and payload against it->tlv_end inside the iterator.","summary":"The MCUboot bootloader's TLV iterator does not check that each entry stays inside the image trailer area, so a crafted image can cause an out-of-bounds read. The sources say the default flash build only fails validation with a bounded read, while the non-default RAM-load configuration has a genuine but bounded out-of-bounds read.","severity":"low","cvss":2.0,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["dfu","embedded","firmware","mcuboot","runtime"],"not_affected_if":["default-config","non-ram-load"],"how_to_check":"- Check whether the device uses MCUboot's non-default `MCUBOOT_RAM_LOAD` configuration, which the sources identify as the affected case.\n- Check the MCUboot version in the build, against the fixed version in the vendor advisory (unknown from the sources given).","fix":"- The sources say the fix is to validate each TLV entry's header and payload against the iterator's end inside `bootutil_tlv_iter_next()`; no fixed version is stated in the sources.","status":"open","published_at":"2026-11-13T02:18:55+00:00","first_seen_at":"2026-11-13T02:41:36+00:00","triaged_at":"2026-11-13T02:43:14+00:00","updated_at":"2026-11-13T02:43:14+00:00","category":"runtime","confidence":0.6,"triage":{"at":"2026-11-13T02:43:14Z","model":"claude-haiku-5-5","output":{"fix":"- The sources say the fix is to validate each TLV entry's header and payload against the iterator's end inside `bootutil_tlv_iter_next()`; no fixed version is stated in the sources.","reach":"local","title":"MCUboot: TLV iterator can read past trailer area during image validation","impact":"low","summary":"The MCUboot bootloader's TLV iterator does not check that each entry stays inside the image trailer area, so a crafted image can cause an out-of-bounds read. The sources say the default flash build only fails validation with a bounded read, while the non-default RAM-load configuration has a genuine but bounded out-of-bounds read.","audience":"developers","category":"runtime","nicknames":[],"who_cares":["mcuboot","embedded","firmware","dfu"],"confidence":0.6,"fix_status":"available","needs_auth":"no","worst_case":"out-of-bounds read during image validation, bounded and not observable","analyst_note":"Confirm the fixed MCUboot version and the exact product ranges from the linked patch and vendor advisory at github.com, since the sources given do not state them.","how_to_check":"- Check whether the device uses MCUboot's non-default `MCUBOOT_RAM_LOAD` configuration, which the sources identify as the affected case.\n- Check the MCUboot version in the build, against the fixed version in the vendor advisory (unknown from the sources given).","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["default-config","non-ram-load"],"who_is_affected":"Teams building firmware on MCUboot, especially devices that use the non-default MCUBOOT_RAM_LOAD configuration, where the out-of-bounds read is genuine though bounded. The sources say the default flash build is contained by bounds checks in the flash read path and results in a clean validation failure at worst. Teams using a different bootloader or none of the affected code can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000853,"input_tokens":5114,"output_tokens":683,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-127915':14A,17A '-2026':13A,16A '3':154C '4':146C 'advanc':112C 'area':8A,40B,160C,220C,235C 'attack':123C,297C 'attacker-control':122C 'authent':179C 'boot/bootutil/src/tlv.c':95C 'bootload':25B 'bootutil':90C,184C,213C,223C 'bound':51B,65B,80B,84B,239C,325C,329C 'bounds-check':238C 'buffer':275C 'build':59B,285C 'byte':147C,155C 'caus':46B 'check':31B,240C 'clamp':270C 'clean':311C 'cnt':269C 'configur':75B,340C 'confin':294C 'consum':256C 'contain':209C 'control':124C 'copi':277C 'corrupt':317C 'craft':43B,194C 'cve':12A,15A 'data':231C,344C 'declar':158C 'default':57B,71B,228C,283C,336C 'describ':167C 'dfu':18B,200C 'disclosur':320C 'effect':280C 'embed':19B 'end':110C,141C,363C 'entri':34B,132C,355C 'everi':254C 'expect':257C,260C,263C 'extend':151C 'fail':61B,246C 'failur':313C 'field':127C 'firmwar':20B 'first':216C 'fix':274C,350C 'flash':58B,234C,243C,284C 'genuin':78B,322C 'guard':104C,212C 'hash':258C 'header':134C,148C,357C 'howev':205C 'imag':10A,38B,44B,97C,116C,195C,225C,230C,266C,343C 'img':185C,214C 'impact':207C 'inform':319C 'insid':36B,364C 'iter':3A,28B,89C,92C,366C 'key':261C 'larger':221C 'len':119C,126C,165C,271C 'load':74B,229C,339C,342C 'loop':103C 'max':224C 'mcuboot':1A,21B,24B,87C,337C 'memcpi':348C 'memori':316C 'never':305C 'next':93C 'non':70B,335C 'non-default':69B,334C 'observ':306C 'ota':204C 'out-of-bound':48B,81B,326C 'out-of-partit':248C 'out-of-region':289C 'pars':182C 'partit':244C,251C,301C 'past':6A,156C,172C 'path':175C 'payload':136C,169C,255C,359C 'pre':178C 'pre-authent':177C 'present':198C 'ram':73B,338C 'ram-load':72B 'rather':314C 'read':5A,52B,66B,85B,149C,236C,252C,293C,330C 'recoveri':203C 'region':292C 'reject':217C 'remain':331C 'residu':279C 'result':144C,303C 'return':163C 'run':171C 'runtim':22B 'say':55B 'sec':268C 'serial':202C 'serial-recoveri':201C 'sig':264C 'signatur':189C 'singl':102C 'sink':232C 'size':226C 'sizeof':114C 'slot':300C 'sourc':54B 'stay':35B,137C 'still':324C 'struct':115C 'surround':211C 'therefor':287C 'though':323C 'tlv':2A,27B,88C,91C,106C,109C,117C,140C,159C,219C,259C,262C,265C,267C,362C 'tlv.it':118C 'tlvs':99C,180C 'trailer':7A,39B,98C 'uncheck':347C 'use':120C 'valid':11A,62B,129C,186C,215C,312C,353C 'verifi':191C 'walk':96C 'whose':302C 'within':138C 'without':128C 'worst':309C 'yield':307C","nicknames":[],"mitigations":[],"who_affected":"Teams building firmware on MCUboot, especially devices that use the non-default MCUBOOT_RAM_LOAD configuration, where the out-of-bounds read is genuine though bounded. The sources say the default flash build is contained by bounds checks in the flash read path and results in a clean validation failure at worst. Teams using a different bootloader or none of the affected code can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["dfu","embedded","firmware","low","mcuboot","runtime"],"campaign_type":null,"search_a":"'-127915':14A,17A '-2026':13A,16A 'area':8A 'cve':12A,15A 'imag':10A 'iter':3A 'mcuboot':1A 'past':6A 'read':5A 'tlv':2A 'trailer':7A 'valid':11A","search_b":"'area':40B 'bootload':25B 'bound':51B,65B,80B,84B 'build':59B 'caus':46B 'check':31B 'configur':75B 'craft':43B 'default':57B,71B 'dfu':18B 'embed':19B 'entri':34B 'fail':61B 'firmwar':20B 'flash':58B 'genuin':78B 'imag':38B,44B 'insid':36B 'iter':28B 'load':74B 'mcuboot':21B,24B 'non':70B 'non-default':69B 'out-of-bound':48B,81B 'ram':73B 'ram-load':72B 'read':52B,66B,85B 'runtim':22B 'say':55B 'sourc':54B 'stay':35B 'tlv':27B 'trailer':39B 'valid':62B","search_c":"'3':154C '4':146C 'advanc':112C 'area':160C,220C,235C 'attack':123C,297C 'attacker-control':122C 'authent':179C 'boot/bootutil/src/tlv.c':95C 'bootutil':90C,184C,213C,223C 'bound':239C,325C,329C 'bounds-check':238C 'buffer':275C 'build':285C 'byte':147C,155C 'check':240C 'clamp':270C 'clean':311C 'cnt':269C 'configur':340C 'confin':294C 'consum':256C 'contain':209C 'control':124C 'copi':277C 'corrupt':317C 'craft':194C 'data':231C,344C 'declar':158C 'default':228C,283C,336C 'describ':167C 'dfu':200C 'disclosur':320C 'effect':280C 'end':110C,141C,363C 'entri':132C,355C 'everi':254C 'expect':257C,260C,263C 'extend':151C 'fail':246C 'failur':313C 'field':127C 'first':216C 'fix':274C,350C 'flash':234C,243C,284C 'genuin':322C 'guard':104C,212C 'hash':258C 'header':134C,148C,357C 'howev':205C 'imag':97C,116C,195C,225C,230C,266C,343C 'img':185C,214C 'impact':207C 'inform':319C 'insid':364C 'iter':89C,92C,366C 'key':261C 'larger':221C 'len':119C,126C,165C,271C 'load':229C,339C,342C 'loop':103C 'max':224C 'mcuboot':87C,337C 'memcpi':348C 'memori':316C 'never':305C 'next':93C 'non':335C 'non-default':334C 'observ':306C 'ota':204C 'out-of-bound':326C 'out-of-partit':248C 'out-of-region':289C 'pars':182C 'partit':244C,251C,301C 'past':156C,172C 'path':175C 'payload':136C,169C,255C,359C 'pre':178C 'pre-authent':177C 'present':198C 'ram':338C 'rather':314C 'read':149C,236C,252C,293C,330C 'recoveri':203C 'region':292C 'reject':217C 'remain':331C 'residu':279C 'result':144C,303C 'return':163C 'run':171C 'sec':268C 'serial':202C 'serial-recoveri':201C 'sig':264C 'signatur':189C 'singl':102C 'sink':232C 'size':226C 'sizeof':114C 'slot':300C 'stay':137C 'still':324C 'struct':115C 'surround':211C 'therefor':287C 'though':323C 'tlv':88C,91C,106C,109C,117C,140C,159C,219C,259C,262C,265C,267C,362C 'tlv.it':118C 'tlvs':99C,180C 'trailer':98C 'uncheck':347C 'use':120C 'valid':129C,186C,215C,312C,353C 'verifi':191C 'walk':96C 'whose':302C 'within':138C 'without':128C 'worst':309C 'yield':307C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-12T22:15:33+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:P/AC:H/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-127915","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-127915","severity":null,"published_at":"2026-11-13T02:18:55+00:00","modified_at":"2026-11-13T02:18:55+00:00","first_seen_at":"2026-11-13T02:41:36+00:00","fetched_at":"2026-11-13T02:41:36+00:00","note":null}],"documents":[{"id":141877,"url":"https://github.com/mcu-tools/mcuboot/commit/90f4e7c3ebe4cf9a5eb7d981220388ffdefd6d19","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":141878,"url":"https://github.com/mcu-tools/mcuboot/security/advisories/GHSA-4fp3-3qw2-25jv","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-12T22:15:33+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"}