build: fix builds on MacOS / clang / newer gcc
What changed, and why it matters
This commit fixes several build-compatibility problems in the Trezor firmware so it compiles on MacOS, clang, and newer gcc. The changes include using the correct local header file, avoiding a special memory section name that MacOS object files reject, silencing a compiler warning about an unused log variable in emulator builds, and fixing a 5-character string being squeezed into a 4-character space. These are primarily build/robustness fixes rather than patches for an active security vulnerability.
Treat as a normal build-fix/portability commit. Reviewers may optionally verify that CAPABILITIES_HEADER is now consistently 4 bytes everywhere it is used, and that the emulator stub for tropic_set_log_sink does not hide needed logging behavior.
Security signals we found
String literal "TRZC" placed into a 4-byte context could write/read a null byte beyond the intended header, though the diff shows the comparison length is 4 and the literal is no longer used.
Include-path fix prevents accidental inclusion of a different version.h if multiple exist, reducing build determinism risk.
Build-only changes; no runtime exploit path is introduced or directly closed in this commit.
Evidence from the diff
The diff addresses four portability/correctness issues: (1) include path ambiguity for version.h is resolved by using a relative ../version.h in bootloader/protob and prodtest; (2) the .buf section attribute on binary_buffer is gated out for TREZOR_EMULATOR because Mach-O does not support that section name; (3) g_lt_log_cli and tropic_set_log_sink are stubbed under TREZOR_EMULATOR to eliminate a set-but-not-used warning; (4) CAPABILITIES_HEADER is changed from the string literal “TRZC” (5 bytes including null terminator) to a 4-byte character array {‘T’,’R’,’Z’,’C’} and memcmp is updated to compare against a 4-byte compound literal. The last item removes a technically undefined string-literal overflow and ensures the header comparison reads exactly 4 bytes.
Changed components
core/embed/projects/bootloader/protob/protob.ccore/embed/projects/prodtest/cmd/common.ccore/embed/projects/prodtest/cmd/prodtest_prodtest.ccore/embed/sec/board_capabilities/inc/sec/board_capabilities.hcore/embed/sec/board_capabilities/stm32/board_capabilities.ccore/embed/sec/tropic/tropic.cInspect captured patch +17 / −7
### core/embed/projects/bootloader/protob/protob.c
@@ -34,11 +34,11 @@
#include <io/power_manager.h>
#endif
+#include "../version.h"
#include "memzero.h"
#include "pb/messages.pb.h"
#include "protob.h"
#include "protob_common.h"
-#include "version.h"
#include "wire/codec_v1.h"
secbool send_user_abort(protob_io_t *iface, const char *msg) {
### core/embed/projects/prodtest/cmd/common.c
@@ -675,8 +675,13 @@ bool check_cert_chain(cli_t* cli, const uint8_t* chain, size_t chain_size,
#define BINARY_MAXSIZE BOOTLOADER_MAXSIZE
#endif
-__attribute__((section(".buf"),
- aligned(4))) static uint8_t binary_buffer[BINARY_MAXSIZE];
+#ifndef TREZOR_EMULATOR
+__attribute__((section(".buf"), aligned(4)))
+#else
+__attribute__((aligned(4)))
+#endif
+static uint8_t binary_buffer[BINARY_MAXSIZE];
+
static size_t binary_len = 0;
static bool binary_update_in_progress = false;
### core/embed/projects/prodtest/cmd/prodtest_prodtest.c
@@ -33,7 +33,7 @@
#include "prodtest.h"
-#include <version.h>
+#include "../version.h"
#define MEM_BUFFER_SIZE (4 * 1024)
static uint8_t mem_buffer[MEM_BUFFER_SIZE];
### core/embed/sec/board_capabilities/inc/sec/board_capabilities.h
@@ -44,7 +44,7 @@ typedef struct __attribute__((packed)) {
//
// Last tag must be terminator or all space used.
-#define CAPABILITIES_HEADER "TRZC"
+#define CAPABILITIES_HEADER {'T', 'R', 'Z', 'C'}
enum CapabilityTag {
TAG_TERMINATOR = 0x00,
### core/embed/sec/board_capabilities/stm32/board_capabilities.c
@@ -41,7 +41,7 @@ void parse_boardloader_capabilities() {
const uint8_t *pos = (const uint8_t *)BOARDCAPS_START;
const uint8_t *end = (const uint8_t *)(BOARDCAPS_START + BOARDCAPS_MAXSIZE);
- if (memcmp(pos, CAPABILITIES_HEADER, 4) != 0) {
+ if (memcmp(pos, (const uint8_t[])CAPABILITIES_HEADER, 4) != 0) {
mpu_restore(mpu_mode);
return;
}
### core/embed/sec/tropic/tropic.c
@@ -45,12 +45,17 @@
#ifdef USE_TROPIC_LOGGING
#include <rtl/printf.h>
+#ifdef TREZOR_EMULATOR
+
+void tropic_set_log_sink(cli_t *cli) { (void)cli; }
+
+#else // !TREZOR_EMULATOR
+
// CLI for libtropic's log output; non-NULL only while a caller has armed it.
static cli_t *g_lt_log_cli = NULL;
void tropic_set_log_sink(cli_t *cli) { g_lt_log_cli = cli; }
-#ifndef TREZOR_EMULATOR
// Log sink called by libtropic's `LT_LOG_*()` macros. On the
// emulator the libtropic POSIX port provides its own implementation.
int lt_port_log(const char *format, ...) {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.