fix(core): mark .buf and .no_dma_buffers sections as NOLOAD
What changed, and why it matters
This commit changes how the Trezor firmware's embedded linker scripts reserve memory for special buffer sections. It marks sections named .buf and .no_dma_buffers as NOLOAD, meaning the linker will reserve RAM space for them but will not include their initial contents in the firmware binary or copy them during startup. Without NOLOAD, these uninitialized buffers could be included in the binary image, increasing its size and potentially causing startup initialization issues. The change is a correctness fix for embedded memory layout, but the commit message does not frame it as a security fix and no exploit is demonstrated.
Treat as a low-risk embedded correctness fix. Review whether the absence of NOLOAD could have caused any buffer to be initialized from flash contents or overlap with other sections in released firmware builds. If a security impact is suspected, request a vendor security advisory or CVE assignment; otherwise, no immediate user action is required beyond normal update cadence.
Security signals we found
Linker section marked NOLOAD to prevent uninitialized buffers from being emitted into firmware image
Memory layout change for DMA and auxiliary RAM buffers across multiple boot stages
No commit message security framing or changelog entry
No CVE, advisory, or researcher attribution in supplied materials
Evidence from the diff
The patch adds the (NOLOAD) attribute to .buf and .no_dma_buffers sections across STM32F4 and STM32U5 linker scripts for boardloader, bootloader, firmware, kernel, and prodtest images. It also reorganizes some scripts so .no_dma_buffers is placed in a dedicated NOLOAD section rather than inside .bss. NOLOAD tells the linker to allocate space in RAM but not to emit contents into the binary or generate LMA/VMA copy logic. This is the correct treatment for uninitialized buffers. The absence of NOLOAD could cause these buffers to be treated as initialized data, inflating binary size and possibly causing startup code to copy garbage or zero-initialized data into them. There is no direct evidence in the diff or references that this is a security vulnerability, but incorrect linker configuration can in principle contribute to memory corruption or information disclosure if buffers overlap or are initialized from flash contents.
Changed components
core/embed/sys/linker/stm32f4/*.ldcore/embed/sys/linker/stm32u58/*.ldcore/embed/sys/linker/stm32u5a/*.ldcore/embed/sys/linker/stm32u5g/*.ldTrezor embedded firmware memory layout for STM32F4 and STM32U5 familiesInspect captured patch +46 / −25
### core/embed/sys/linker/stm32f4/boardloader.ld
@@ -56,7 +56,7 @@ SECTIONS {
. = ALIGN(4);
} >FB1
- .buf : ALIGN(4) {
+ .buf (NOLOAD) : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >AUX1_RAM
### core/embed/sys/linker/stm32f4/bootloader.ld
@@ -61,7 +61,7 @@ SECTIONS {
. = ALIGN(4);
} >FB1
- .buf : ALIGN(4) {
+ .buf (NOLOAD) : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
*(.no_dma_buffers*);
### core/embed/sys/linker/stm32f4/firmware.ld
@@ -75,7 +75,7 @@ SECTIONS {
. = ABSOLUTE(ORIGIN(AUX1_RAM) + LENGTH(AUX1_RAM)); /* this explicitly sets the end of the heap */
} >AUX1_RAM
- .data_ccm : ALIGN(4) {
+ .data_ccm (NOLOAD) : ALIGN(4) {
*(.no_dma_buffers*);
. = ALIGN(4);
} >AUX2_RAM
### core/embed/sys/linker/stm32f4/kernel.ld
@@ -57,7 +57,7 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD) : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >DMABUF
### core/embed/sys/linker/stm32f4/prodtest.ld
@@ -74,6 +74,13 @@ SECTIONS {
. = ALIGN(4);
} >AUX1_RAM
+ .buf (NOLOAD) : ALIGN(4) {
+ *(.no_dma_buffers*);
+ . = ALIGN(4);
+ *(.buf*);
+ . = ALIGN(4);
+ } >AUX1_RAM
+
.fb : ALIGN(4) {
*(.fb1*);
. = ALIGN(4);
### core/embed/sys/linker/stm32u58/boardloader.ld
@@ -52,7 +52,7 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD) : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >AUX1_RAM
### core/embed/sys/linker/stm32u58/bootloader.ld
@@ -65,7 +65,7 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
*(.buf*);
. = ALIGN(4);
*(.no_dma_buffers*);
### core/embed/sys/linker/stm32u58/firmware.ld
@@ -64,16 +64,20 @@ SECTIONS {
} > AUX1_RAM
.bss : ALIGN(4) {
- *(.no_dma_buffers*);
*(.bss*);
. = ALIGN(4);
} >AUX1_RAM
+ .no_dma_buffers (NOLOAD): ALIGN(4) {
+ *(.no_dma_buffers*);
+ . = ALIGN(4);
+ } >AUX1_RAM
+
.stack : ALIGN(8) {
. += 32K; /* Overflow causes UsageFault */
} >AUX2_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >AUX2_RAM
### core/embed/sys/linker/stm32u58/kernel.ld
@@ -64,9 +64,14 @@ SECTIONS {
}
.bss : ALIGN(4) {
+ *(.bss*);
+ . = ALIGN(4);
+ } >MAIN_RAM
+
+ .buf (NOLOAD): ALIGN(4) {
*(.no_dma_buffers*);
+ . = ALIGN(4);
*(.buf*);
- *(.bss*);
. = ALIGN(4);
} >MAIN_RAM
### core/embed/sys/linker/stm32u58/prodtest.ld
@@ -85,7 +85,7 @@ SECTIONS {
. = ALIGN(4);
} >AUX1_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD) : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
*(.no_dma_buffers*);
### core/embed/sys/linker/stm32u5a/boardloader.ld
@@ -53,7 +53,7 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >AUX1_RAM
### core/embed/sys/linker/stm32u5a/bootloader.ld
@@ -52,7 +52,7 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD) : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
*(.no_dma_buffers*);
### core/embed/sys/linker/stm32u5a/firmware.ld
@@ -74,12 +74,13 @@ SECTIONS {
} > AUX1_RAM
.bss : ALIGN(4) {
- *(.no_dma_buffers*);
*(.bss*);
. = ALIGN(4);
} >AUX1_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
+ *(.no_dma_buffers*);
+ . = ALIGN(4);
*(.buf*);
. = ALIGN(4);
} >AUX1_RAM
### core/embed/sys/linker/stm32u5a/kernel.ld
@@ -61,7 +61,6 @@ SECTIONS {
}
.bss : ALIGN(4) {
- *(.no_dma_buffers*);
*(.bss*);
. = ALIGN(4);
} >MAIN_RAM
@@ -76,7 +75,9 @@ SECTIONS {
. = ALIGN(4);
} >FB2_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
+ *(.no_dma_buffers*);
+ . = ALIGN(4);
*(.buf*);
. = ALIGN(4);
} >MAIN_RAM
### core/embed/sys/linker/stm32u5a/prodtest.ld
@@ -71,7 +71,7 @@ SECTIONS {
} >AUX1_RAM
/* D003 has no AUX2_RAM, so .buf shares AUX1_RAM with .data/.bss. */
- .buf : ALIGN(4) {
+ .buf (NOLOAD) : ALIGN(4) {
*(.buf*);
. = ALIGN(4);
*(.no_dma_buffers*);
### core/embed/sys/linker/stm32u5g/boardloader.ld
@@ -53,7 +53,7 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
*(.buf*);
. = ALIGN(4);
} >AUX1_RAM
### core/embed/sys/linker/stm32u5g/bootloader.ld
@@ -61,7 +61,7 @@ SECTIONS {
. = ALIGN(4);
} >MAIN_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
*(.buf*);
. = ALIGN(4);
*(.no_dma_buffers*);
### core/embed/sys/linker/stm32u5g/firmware.ld
@@ -74,12 +74,13 @@ SECTIONS {
} > AUX1_RAM
.bss : ALIGN(4) {
- *(.no_dma_buffers*);
*(.bss*);
. = ALIGN(4);
} >AUX1_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
+ *(.no_dma_buffers*);
+ . = ALIGN(4);
*(.buf*);
. = ALIGN(4);
} >AUX1_RAM
### core/embed/sys/linker/stm32u5g/kernel.ld
@@ -61,7 +61,6 @@ SECTIONS {
}
.bss : ALIGN(4) {
- *(.no_dma_buffers*);
*(.bss*);
. = ALIGN(4);
} >MAIN_RAM
@@ -76,7 +75,9 @@ SECTIONS {
. = ALIGN(4);
} >FB2_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD): ALIGN(4) {
+ *(.no_dma_buffers*);
+ . = ALIGN(4);
*(.buf*);
. = ALIGN(4);
} >MAIN_RAM
### core/embed/sys/linker/stm32u5g/prodtest.ld
@@ -80,7 +80,6 @@ SECTIONS {
_image_flash_end = LOADADDR(.data) + SIZEOF(.data);
.bss : ALIGN(4) {
- *(.no_dma_buffers*);
*(.bss*);
. = ALIGN(4);
} >AUX1_RAM
@@ -95,7 +94,9 @@ SECTIONS {
. = ALIGN(4);
} >FB2_RAM
- .buf : ALIGN(4) {
+ .buf (NOLOAD) : ALIGN(4) {
+ *(.no_dma_buffers*);
+ . = ALIGN(4);
*(.buf*);
. = ALIGN(4);
} >AUX1_RAMWhy this scored 44/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.