fix(core/bootloader): fix progress bar delay when installing firmware
What changed, and why it matters
This commit fixes a user-interface timing issue in the Trezor bootloader. Previously, the firmware-installation progress bar could start moving before the user had actually confirmed the update on the device screen. The change makes the progress bar wait until the user explicitly confirms, so the on-screen feedback matches the real installation state. There is no direct evidence this is a security vulnerability, but it removes a small window where UI state could be misleading during a firmware update.
Treat as a minor UI/UX hardening change rather than a security fix requiring urgent response. Include in regular firmware release notes. If the project has a bug bounty or security classification process, this likely does not qualify as a vulnerability on its own, but reviewers may verify that no other workflow state can be advanced before confirmation.
Security signals we found
UI state desynchronization between received data and user confirmation
Progress bar could advance before explicit user approval
Bootloader firmware update workflow modified
Evidence from the diff
In the bootloader firmware-update workflow (wf_firmware_update.c), a new confirmed boolean field is added to the update context. The progress-bar callback fw_data_received now checks context->confirmed before advancing the progress bar, instead of checking whether at least one firmware block has been received (context->firmware_block > 0). The confirmed flag is set immediately after ui_screen_install_start() is shown and the user has approved the update. This prevents the progress indicator from updating during the initial unconfirmed data reception phase.
Changed components
core/embed/projects/bootloader/workflow/wf_firmware_update.cTrezor bootloader firmware update UIInspect captured patch +5 / −2
diff --git a/core/embed/projects/bootloader/.changelog.d/5484.fixed b/core/embed/projects/bootloader/.changelog.d/5484.fixed
new file mode 100644
index 00000000..bdb24719
--- /dev/null
+++ b/core/embed/projects/bootloader/.changelog.d/5484.fixed
@@ -0,0 +1 @@
+Fixed progress bar delay when installing firmware.
diff --git a/core/embed/projects/bootloader/workflow/wf_firmware_update.c b/core/embed/projects/bootloader/workflow/wf_firmware_update.c
index 8ca2ee1a..68f821e0 100644
--- a/core/embed/projects/bootloader/workflow/wf_firmware_update.c
+++ b/core/embed/projects/bootloader/workflow/wf_firmware_update.c
@@ -86,6 +86,7 @@ typedef struct {
size_t headers_offset; // offset of headers in the first block
size_t read_offset; // offset of the next read data in the chunk buffer
uint32_t chunk_size; // size of already received chunk data
+ bool confirmed; // true if the firmware is confirmed by the user
#ifdef USE_SECMON_VERIFICATION
size_t secmon_code_offset; // offset of the secmon code in the first block
size_t secmon_code_size; // size of the secmon code
@@ -171,8 +172,8 @@ static void fw_data_received(size_t len, void *ctx) {
firmware_update_ctx_t *context = (firmware_update_ctx_t *)ctx;
context->chunk_size += len;
- // update loader but skip first block
- if (context->firmware_block > 0) {
+ // update loader only after the update is confirmed
+ if (context->confirmed) {
ui_screen_install_progress_upload(
1000 *
(context->firmware_block * IMAGE_CHUNK_SIZE + context->chunk_size) /
@@ -402,6 +403,7 @@ static upload_status_t process_msg_FirmwareUpload(protob_io_t *iface,
}
ui_screen_install_start();
+ ctx->confirmed = true;
// if firmware is not upgrade, erase storage
if (sectrue != should_keep_seed) {
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.