fix(core/bootloader): fix bootloader size alignment
What changed, and why it matters
This commit adjusts how the Trezor bootloader's length is calculated and pads the bootloader image to a 512-byte boundary. The old calculation added the sizes of two memory sections, which could produce a value that does not match the actual padded image size. The new calculation uses a dedicated end marker, and the linker script now explicitly fills unused space with zeros and aligns the image. This is a defensive fix in low-level firmware packaging; it does not by itself show an exploitable bug, but misaligned or incorrectly reported bootloader sizes could theoretically cause verification or update failures.
Treat as a hardening/maintenance fix. Review whether the old `_codelen` value was consumed by any signature, hash, or update-header generation, and verify that downstream tooling now receives the expected aligned size. No immediate user action is required.
Security signals we found
Linker-level size calculation changed from section-size sum to start-to-end span
New explicit zero-fill and 512-byte alignment of bootloader image
Bootloader boundary definition changed, which may affect integrity/verification metadata
No changelog entry provided
Evidence from the diff
The patch modifies the STM32F4 and STM32U58 bootloader linker scripts. It replaces _codelen = SIZEOF(.flash) + SIZEOF(.data) with _codelen = _bootloader_code_end - ADDR(.flash), and adds a final .flash output section that pads the remainder of the bootloader area with zeros and aligns to 512 bytes, defining _bootloader_code_end at that point. The change ensures _codelen reflects the actual aligned span from the start of flash to the aligned end, rather than the sum of section sizes. This can matter for boardloader parsing, integrity checks, or firmware update headers that expect a fixed alignment.
Changed components
core/embed/sys/linker/stm32f4/bootloader.ldcore/embed/sys/linker/stm32u58/bootloader.ldTrezor Core bootloader image layout and size reportingInspect captured patch +19 / −2
diff --git a/core/embed/sys/linker/stm32f4/bootloader.ld b/core/embed/sys/linker/stm32f4/bootloader.ld
index 3207dd85..6003aeb1 100644
--- a/core/embed/sys/linker/stm32f4/bootloader.ld
+++ b/core/embed/sys/linker/stm32f4/bootloader.ld
@@ -22,7 +22,7 @@ _bss_section_end = ADDR(.bss) + SIZEOF(.bss);
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
-_codelen = SIZEOF(.flash) + SIZEOF(.data);
+_codelen = _bootloader_code_end - ADDR(.flash);
SECTIONS {
.header : ALIGN(4) {
@@ -73,4 +73,12 @@ SECTIONS {
. = ALIGN(8);
} >BOOT_ARGS
+ .flash : ALIGN(4) {
+ /* Pad the rest of bootloader area with zeros */
+ BYTE(0x00)
+ FILL(0x00)
+ /* Use alignment required by the boardloader */
+ . = ALIGN(512);
+ _bootloader_code_end = .;
+ } >FLASH
}
diff --git a/core/embed/sys/linker/stm32u58/bootloader.ld b/core/embed/sys/linker/stm32u58/bootloader.ld
index 4853dcf4..4ff452de 100644
--- a/core/embed/sys/linker/stm32u58/bootloader.ld
+++ b/core/embed/sys/linker/stm32u58/bootloader.ld
@@ -23,7 +23,7 @@ _bss_section_end = ADDR(.bss) + SIZEOF(.bss);
_bootargs_ram_start = BOOTARGS_START;
_bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE;
-_codelen = SIZEOF(.flash) + SIZEOF(.data);
+_codelen = _bootloader_code_end - ADDR(.flash);
SECTIONS {
.header : ALIGN(4) {
@@ -80,4 +80,13 @@ SECTIONS {
*(.boot_args*);
. = ALIGN(8);
} >BOOT_ARGS
+
+ .flash : ALIGN(4) {
+ /* Pad the rest of bootloader area with zeros */
+ BYTE(0x00)
+ FILL(0x00)
+ /* Use alignment required by the boardloader */
+ . = ALIGN(512);
+ _bootloader_code_end = .;
+ } >FLASH
}
Why this scored 43/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.