Skip to content

boot: bootutil: require exact hash TLV length#2802

Open
d3zd3z wants to merge 1 commit into
mcu-tools:mainfrom
d3zd3z:fix-09
Open

boot: bootutil: require exact hash TLV length#2802
d3zd3z wants to merge 1 commit into
mcu-tools:mainfrom
d3zd3z:fix-09

Conversation

@d3zd3z

@d3zd3z d3zd3z commented Jul 24, 2026

Copy link
Copy Markdown
Member

boot_save_boot_status() reads the image hash out of the manifest into a
fixed-size stack buffer, uint8_t image_hash[IMAGE_HASH_SIZE]. The only length
check on the hash TLV was an upper bound:

if (len > sizeof(image_hash)) {
    return -1;
}
rc = flash_area_read(fap, offset, image_hash, len);

So a TLV shorter than the configured hash length was accepted, and
flash_area_read() filled only the first len bytes. The rest of image_hash
was left holding whatever happened to be on the stack.

Further down, the copy into the boot record uses the buffer size rather than
len:

memcpy(buf + offset, image_hash, sizeof(image_hash));

so that stale stack content is copied into the record that
boot_add_data_to_shared_area() places in the shared data area, and a
consumer of the record sees it as part of the measurement.

A hash TLV shorter than the hash size is malformed, so this rejects it outright
instead of reading it partially. bootutil_img_validate() already applies the
same exact-length check (if (len != sizeof(hash))), so an image that passes
validation is unaffected by this change; it only tightens the path taken when
the slot is not hash-validated.

Only compiled under MCUBOOT_MEASURED_BOOT.

Testing: cargo test in sim/ passes (25 passed, 0 failed). Note that the sim
does not build boot/bootutil/src/boot_record.c and never defines
MCUBOOT_MEASURED_BOOT, so that is a no-regression run rather than coverage of
this code; the edited file was additionally compiled standalone with measured
boot enabled, with no diagnostics.

boot_save_boot_status() only checked that the image hash TLV was no
larger than the image_hash buffer, so a TLV shorter than the hash
length was accepted and flash_area_read() filled just the first len
bytes. The tail of image_hash was then left with whatever happened to
be on the stack, and the later memcpy() into the boot record copies
sizeof(image_hash) bytes unconditionally, so that stale stack content
ends up in the boot record placed in the shared data area. A short
hash TLV is malformed, so reject it outright by requiring the exact
length, matching the check bootutil_img_validate() already performs.

Assisted-by: Claude:opus-5
Signed-off-by: David Brown <david.brown@linaro.org>
@d3zd3z
d3zd3z requested a review from davidvincze as a code owner July 24, 2026 20:29
Copilot AI review requested due to automatic review settings July 24, 2026 20:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@d3zd3z
d3zd3z requested review from de-nordic and nordicjm July 24, 2026 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants