Merge remote-tracking branch 'agent/benma-agent/bootloader-descriptor-compat'
What changed, and why it matters
This commit relaxes a version check in the BitBox02 bootloader upgrade code. Previously, the firmware installer required that a stage0 bootloader descriptor's version exactly matched the currently expected image version. Now it accepts descriptors whose version differs, as long as the magic number and product ID still match. The change is framed as improving compatibility across bootloader descriptor layouts, not as fixing a security bug. The accompanying tests verify that both older and newer stage0 versions are accepted.
Treat as a hardening/compatibility change rather than an active vulnerability. Review whether removing the exact stage0_version check could allow a mismatched stage0 bootloader to pass descriptor validation, and confirm that downstream checks (e.g., signature verification, development-flag checks, stage1 header validation) still enforce the intended security policy. No urgent patch is indicated by the diff alone.
Security signals we found
Strict version equality check removed from bootloader descriptor parsing
Change located in bootloader upgrade / firmware installer verification path
No bounds, length, or pointer validation changes observed
No explicit security framing in commit title or message
Evidence from the diff
In src/bootloader_upgrade/firmware_installer_check.c, the _read_stage0_descriptor() function no longer validates descriptor_out->stage0_version == BB02_STAGE0_IMAGE_VERSION. It only checks the descriptor magic and product ID. Unit tests were updated to assert that development/production detection works when stage0_version is set to 1 and to BB02_STAGE0_IMAGE_VERSION + 1. This makes the stage0 descriptor parser more tolerant of version drift between the installed stage0 bootloader and the firmware performing the upgrade check.
Changed components
src/bootloader_upgrade/firmware_installer_check.ctest/unit-test/test_bootloader_upgrade_check.cInspect captured patch +19 / −7
### src/bootloader_upgrade/firmware_installer_check.c
@@ -57,8 +57,8 @@ static bool _read_stage0_descriptor(
return false;
}
memcpy(descriptor_out, descriptor, sizeof(*descriptor_out));
+ // The stage0 image version can differ from ours without changing the descriptor layout.
return descriptor_out->magic == BB02_STAGE0_DESCRIPTOR_MAGIC &&
- descriptor_out->stage0_version == BB02_STAGE0_IMAGE_VERSION &&
descriptor_out->product_id == BB02_STAGE1_PRODUCT_ID;
}
### test/unit-test/test_bootloader_upgrade_check.c
@@ -59,8 +59,8 @@ static void test_legacy_development_markers_absent(void** state)
static void test_development_stage0_descriptor(void** state)
{
(void)state;
- const bb02_stage0_descriptor_t descriptor = {
- .stage0_version = BB02_STAGE0_IMAGE_VERSION,
+ bb02_stage0_descriptor_t descriptor = {
+ .stage0_version = 1u,
.product_id = BB02_STAGE1_PRODUCT_ID,
.flags = BB02_STAGE0_FLAG_DEVELOPMENT,
.magic = BB02_STAGE0_DESCRIPTOR_MAGIC,
@@ -69,13 +69,17 @@ static void test_development_stage0_descriptor(void** state)
assert_true(bootloader_upgrade_is_development_bootloader(
&descriptor, NULL, legacy_bootloader, sizeof(legacy_bootloader)));
+
+ descriptor.stage0_version = BB02_STAGE0_IMAGE_VERSION + 1u;
+ assert_true(bootloader_upgrade_is_development_bootloader(
+ &descriptor, NULL, legacy_bootloader, sizeof(legacy_bootloader)));
}
static void test_development_stage1_header(void** state)
{
(void)state;
- const bb02_stage0_descriptor_t stage0_descriptor = {
- .stage0_version = BB02_STAGE0_IMAGE_VERSION,
+ bb02_stage0_descriptor_t stage0_descriptor = {
+ .stage0_version = 1u,
.product_id = BB02_STAGE1_PRODUCT_ID,
.flags = 0,
.magic = BB02_STAGE0_DESCRIPTOR_MAGIC,
@@ -92,6 +96,10 @@ static void test_development_stage1_header(void** state)
assert_true(bootloader_upgrade_is_development_bootloader(
&stage0_descriptor, &stage1_header, legacy_bootloader, sizeof(legacy_bootloader)));
+
+ stage0_descriptor.stage0_version = BB02_STAGE0_IMAGE_VERSION + 1u;
+ assert_true(bootloader_upgrade_is_development_bootloader(
+ &stage0_descriptor, &stage1_header, legacy_bootloader, sizeof(legacy_bootloader)));
}
static void test_development_stage1_header_future_header_version(void** state)
@@ -120,8 +128,8 @@ static void test_development_stage1_header_future_header_version(void** state)
static void test_production_stage0_descriptor_skips_legacy_markers(void** state)
{
(void)state;
- const bb02_stage0_descriptor_t stage0_descriptor = {
- .stage0_version = BB02_STAGE0_IMAGE_VERSION,
+ bb02_stage0_descriptor_t stage0_descriptor = {
+ .stage0_version = 1u,
.product_id = BB02_STAGE1_PRODUCT_ID,
.flags = 0,
.magic = BB02_STAGE0_DESCRIPTOR_MAGIC,
@@ -141,6 +149,10 @@ static void test_production_stage0_descriptor_skips_legacy_markers(void** state)
assert_false(bootloader_upgrade_is_development_bootloader(
&stage0_descriptor, &stage1_header, legacy_bootloader, sizeof(legacy_bootloader)));
+
+ stage0_descriptor.stage0_version = BB02_STAGE0_IMAGE_VERSION + 1u;
+ assert_false(bootloader_upgrade_is_development_bootloader(
+ &stage0_descriptor, &stage1_header, legacy_bootloader, sizeof(legacy_bootloader)));
}
int main(void)Why this scored 26/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.