AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Low 45 Bitcoin

fix(core/bootloader): keep the full block length for block-0 retries

Public commit record

What the developer wrote

Authored by tychovrahe

85/100 · Strong
fix(core/bootloader): keep the full block length for block-0 retries

Block 0 is the only block fetched in two requests: an initial
IMAGE_INIT_CHUNK_SIZE prefetch so the headers can be validated, then the
remainder. `chunk_requested` was serving three roles at once -- request size,
expected buffer fill, and the amount still owed on `remaining` -- and after the
header prefetch it holds only the remainder.

A retry then asked for that remainder from offset 0. The size check compared
`chunk_size` against `chunk_requested + read_offset`, i.e. the remainder against
itself, so it passed and `on_chunk` received a truncated block: the first
`chunk_limit - IMAGE_INIT_CHUNK_SIZE` bytes sitting at buffer offset 0. The hash
then necessarily mismatched, so the retry budget burned down and the upload
aborted. Block-0 retries could never succeed -- on T3W1 that is a 256 KB block,
where a transient BLE error is most likely.

Replace `chunk_requested` with `chunk_expected`: the bytes the buffer must hold
for the chunk to be complete, i.e. the whole block. It is the only field of its
kind left -- every request is derived from it, `remaining` is decremented by what
actually arrived, and `read_offset` goes back to being purely a buffer write
offset. The retry re-fetches the whole block from its start, and the size check
compares against what the buffer must actually hold.

No behavioural change on the success path: the bytes asked for at each request
site are the same as before, and what the old check computed is exactly what
`chunk_expected` now holds.

Alongside, in the same code: the image-size validation becomes an early guard in
`run_image_upload`, which is what guarantees a full init chunk to prefetch;
`confirmed` folds into `headers_parsed`, both having been set at the same point;
and the result dispatch becomes a switch.

The same bug is in wf_firmware_update.c on main; this fix is written against the
extracted engine but applies there unchanged.

[no changelog]

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Uses a recognizable type or scope✓ Provides detailed explanatory context
The short version

What changed, and why it matters

This commit fixes a bug in the Trezor bootloader's firmware-update code. When updating firmware, the first block of data is fetched in two pieces: a small initial 'header prefetch,' then the rest. If a communication error happened and the bootloader tried to retry, it accidentally asked for only the leftover remainder but placed it at the start of the buffer. That produced a corrupted block, the hash check failed, every retry failed, and the firmware update aborted. The fix makes retries request the whole first block again from the beginning. There is no evidence this bug was exploitable by an attacker; it appears to be a reliability defect that could brick or stall legitimate updates, especially over Bluetooth on the T3W1 model.

Recommended action

Treat as a reliability/availability fix rather than an exploitable vulnerability. Apply the patch and verify block-0 retry behavior under simulated transport errors. Consider patching wf_firmware_update.c on main as noted by the commit author. No CVE or security advisory appears necessary unless further evidence shows the truncated-block condition can be induced and exploited.

Security signals we found

01

Firmware update reliability bug in bootloader

02

Block-0 retry path truncated data before hash verification

03

Hash mismatch caused by buffer offset/size mismatch, not by attacker

04

Retry budget exhaustion could deny legitimate firmware updates

05

Wireless/BLE transport noted as most affected

06

No authentication bypass, buffer overflow, or code execution identified in diff

Risk score

Why this scored 45/100

Our methodology →
Potential impact 12/30
Exploitability 5/25
Stealth signal 6/15
Affected reach 10/15
Confidence 8/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.