1. optimize the guidance update logic, and fix memory allocation 2. chore: update ci
What changed, and why it matters
This firmware update fixes a memory leak and cleans up boot-update logic in a hardware crypto wallet. The most concrete security-relevant change is adding a missing SRAM_FREE(buffer) call in BinarySearchBootHead, which prevents a small memory allocation from never being released. Other changes replace hardcoded 4096-byte values with a SECTOR_SIZE constant and remove a production-only conditional around NeedUpdateBoot. The commit message mentions 'fix memory allocation' but does not frame the change as a security fix.
Treat as a routine maintenance/fix patch. Review the boot update path for additional missing resource frees and verify that removing the BUILD_PRODUCTION guard does not enable unintended boot updates in non-production builds. No urgent security response is indicated by the diff alone.
Security signals we found
Memory leak fix: SRAM_FREE(buffer) added in BinarySearchBootHead success path
Type/size consistency: replaced literal 4096 with SECTOR_SIZE in boot update flash operations
Logic simplification: removed BUILD_PRODUCTION conditional guarding NeedUpdateBoot
Heap size reduction: configTOTAL_HEAP_SIZE decreased by 10 KiB
Return value correction: UpdateBootFromFlash returns -1 instead of false for int32_t return type
Evidence from the diff
In src/boot_update.c, g_fileUnit is resized/typed via SECTOR_SIZE instead of a literal 4096, and three QspiFlashEraseAndWrite calls now use SECTOR_SIZE consistently. BinarySearchBootHead now frees its temporary buffer when the magic number is found. UpdateBootFromFlash returns -1 instead of false on invalid num. In src/config/version.c, the BUILD_PRODUCTION preprocessor guard around NeedUpdateBoot is removed, making the function always active. FreeRTOSConfig.h reduces configTOTAL_HEAP_SIZE from 450 KiB to 440 KiB. No explicit security advisory, CVE, or researcher attribution is present.
Changed components
src/boot_update.csrc/config/version.cexternal/FreeRTOS/FreeRTOSConfig.hInspect captured patch +8 / −17
diff --git a/external/FreeRTOS/FreeRTOSConfig.h b/external/FreeRTOS/FreeRTOSConfig.h
index 9ae5e55..e3b8b22 100644
--- a/external/FreeRTOS/FreeRTOSConfig.h
+++ b/external/FreeRTOS/FreeRTOSConfig.h
@@ -62,7 +62,7 @@ extern uint32_t SystemCoreClock;
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 56 )
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
-#define configTOTAL_HEAP_SIZE ((size_t)1024 * 450)
+#define configTOTAL_HEAP_SIZE ((size_t)1024 * 440)
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
diff --git a/src/boot_update.c b/src/boot_update.c
index c5f7c81..5b4bd8b 100644
--- a/src/boot_update.c
+++ b/src/boot_update.c
@@ -19,7 +19,7 @@ LV_FONT_DECLARE(openSans_24);
#define APP_END_ADDR (0x2000000)
static const uint8_t MAGIC_NUMBER[] = {'m', 'h', '1', '9', '0', '3', 'b', 'o', 'o', 't', 'u', 'p', 'd', 'a', 't', 'e'};
-static uint8_t g_fileUnit[4096] = {0};
+static uint8_t g_fileUnit[SECTOR_SIZE] = {0};
static uint32_t BinarySearchBootHead(void)
{
@@ -32,6 +32,7 @@ static uint32_t BinarySearchBootHead(void)
memcpy_s(buffer, SECTOR_SIZE, (uint32_t *)(APP_ADDR + i * SECTOR_SIZE), SECTOR_SIZE);
if (memcmp(buffer, MAGIC_NUMBER, MAGIC_NUMBER_SIZE) == 0) {
printf("find magic number\n");
+ SRAM_FREE(buffer);
return i;
}
}
@@ -59,7 +60,7 @@ int32_t UpdateBootFromFlash(void)
printf("num = %d\n", num);
if (num <= 0) {
osKernelUnlock();
- return false;
+ return -1;
}
uint32_t len, offset, crcCalc, readCrc, writeAddr = 0x1001000;
uint32_t baseAddr = APP_ADDR + num * SECTOR_SIZE;
@@ -81,7 +82,7 @@ int32_t UpdateBootFromFlash(void)
memset(g_fileUnit, 0xFF, sizeof(g_fileUnit));
memcpy(g_fileUnit, (uint32_t *)(baseAddr + 4 + 32 + 0x30 + MAGIC_NUMBER_SIZE), BOOT_HEAD_SIZE);
- QspiFlashEraseAndWrite(0x01000000, g_fileUnit, 4096);
+ QspiFlashEraseAndWrite(0x01000000, g_fileUnit, SECTOR_SIZE);
sha256_update(&ctx, (uint32_t *)(baseAddr + 4 + 32 + MAGIC_NUMBER_SIZE), 0x134);
crcCalc = crc32_ieee(0, (uint32_t *)(baseAddr + 4 + 32 + MAGIC_NUMBER_SIZE), 0x134);
@@ -113,7 +114,7 @@ int32_t UpdateBootFromFlash(void)
if (memcmp(hash, calHash, 32) == 0) {
printf("update success\n");
memset(g_fileUnit, 0xFF, sizeof(g_fileUnit));
- QspiFlashEraseAndWrite((uint32_t *)(APP_END_ADDR - 4096), g_fileUnit, 4096);
+ QspiFlashEraseAndWrite((uint32_t *)(APP_END_ADDR - SECTOR_SIZE), g_fileUnit, SECTOR_SIZE);
memset(g_fileUnit, 0, sizeof(g_fileUnit));
return 0;
} else {
diff --git a/src/config/version.c b/src/config/version.c
index d9e0b90..44f28eb 100644
--- a/src/config/version.c
+++ b/src/config/version.c
@@ -84,12 +84,8 @@ void GetBootVersionNumber(char *version)
snprintf(version, SOFTWARE_VERSION_MAX_LEN, "%d.%d.%d", major, minor, build);
}
-#ifdef BUILD_PRODUCTION
bool NeedUpdateBoot(void)
{
-#ifndef BUILD_PRODUCTION
- return false;
-#endif
uint32_t major, minor, build;
if (GetBootSoftwareVersion(&major, &minor, &build) == false) {
return true;
@@ -152,10 +148,4 @@ static bool GetBootSoftwareVersionFormData(uint32_t *major, uint32_t *minor, uin
*build = 0;
}
return succ;
-}
-#else
-bool NeedUpdateBoot(void)
-{
- return false;
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file
Why this scored 41/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.