Skip to content

Commit e4e96ad

Browse files
committed
Reject valid zero-size delta images
F/2268
1 parent 0c4be70 commit e4e96ad

3 files changed

Lines changed: 89 additions & 3 deletions

File tree

src/update_flash.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -562,8 +562,13 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
562562
uint8_t *base_hash;
563563

564564
if (boot->fw_size == 0) {
565-
/* Resume after powerfail can leave boot header erased; bound by partition size. */
566-
boot->fw_size = WOLFBOOT_PARTITION_SIZE - IMAGE_HEADER_SIZE;
565+
if ((boot->hdr != NULL) &&
566+
(*((uint32_t *)boot->hdr) != WOLFBOOT_MAGIC)) {
567+
/* Resume after powerfail can leave the boot header erased. */
568+
boot->fw_size = WOLFBOOT_PARTITION_SIZE - IMAGE_HEADER_SIZE;
569+
} else {
570+
return -1;
571+
}
567572
}
568573

569574
/* Use biggest size for the swap */

tools/unit-tests/Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ endif
4545
TESTS:=unit-parser unit-fdt unit-extflash unit-string unit-spi-flash unit-aes128 \
4646
unit-aes256 unit-chacha20 unit-pci unit-mock-state unit-sectorflags \
4747
unit-image unit-image-rsa unit-nvm unit-nvm-flagshome unit-enc-nvm \
48-
unit-enc-nvm-flagshome unit-delta unit-update-flash \
48+
unit-enc-nvm-flagshome unit-delta unit-update-flash unit-update-flash-delta \
4949
unit-update-flash-self-update \
5050
unit-update-flash-enc unit-update-ram unit-pkcs11_store unit-psa_store unit-disk \
5151
unit-update-disk unit-multiboot unit-boot-x86-fsp unit-qspi-flash unit-tpm-rsa-exp \
@@ -98,6 +98,10 @@ unit-psa_store:CFLAGS+=-I$(WOLFBOOT_LIB_WOLFPSA) -DMOCK_PARTITIONS -DMOCK_KEYVAU
9898
unit-update-flash:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
9999
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT \
100100
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
101+
unit-update-flash-delta:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
102+
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT \
103+
-DDELTA_UPDATES -DDELTA_BLOCK_SIZE=512 -D__WOLFBOOT \
104+
-DWOLFBOOT_ORIGIN=MOCK_ADDRESS_BOOT -DBOOTLOADER_PARTITION_SIZE=WOLFBOOT_PARTITION_SIZE
101105
unit-update-flash-self-update:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
102106
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT \
103107
-DRAM_CODE -DARCH_SIM -DUNIT_TEST_SELF_UPDATE_ONLY \
@@ -267,6 +271,10 @@ unit-delta: ../../include/target.h unit-delta.c
267271
unit-update-flash: ../../include/target.h unit-update-flash.c
268272
gcc -o $@ unit-update-flash.c ../../src/image.c $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)
269273

274+
unit-update-flash-delta: ../../include/target.h unit-update-flash.c
275+
gcc -o $@ unit-update-flash.c ../../src/image.c ../../src/delta.c \
276+
$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)
277+
270278
unit-update-flash-enc:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
271279
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT \
272280
-DPART_SWAP_EXT -DEXT_ENCRYPTED -DENCRYPT_WITH_CHACHA -DHAVE_CHACHA \

tools/unit-tests/unit-update-flash.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,22 @@ START_TEST (test_update_toolarge) {
672672
cleanup_flash();
673673
}
674674

675+
START_TEST (test_zero_size_update_rejected)
676+
{
677+
int ret;
678+
679+
reset_mock_stats();
680+
prepare_flash();
681+
add_payload(PART_BOOT, 1, 0);
682+
add_payload(PART_UPDATE, 2, 0);
683+
684+
ret = wolfBoot_update(1);
685+
ck_assert_int_eq(ret, -1);
686+
687+
cleanup_flash();
688+
}
689+
END_TEST
690+
675691
START_TEST (test_invalid_sha) {
676692
uint8_t bad_digest[SHA256_DIGEST_SIZE];
677693
reset_mock_stats();
@@ -817,6 +833,50 @@ START_TEST (test_diffbase_version_reads)
817833
cleanup_flash();
818834
}
819835
END_TEST
836+
837+
#ifdef DELTA_UPDATES
838+
START_TEST (test_delta_zero_size_valid_header_rejected_without_recovery_heuristic)
839+
{
840+
struct wolfBoot_image boot, update, swap;
841+
int ret;
842+
843+
reset_mock_stats();
844+
prepare_flash();
845+
add_payload(PART_BOOT, 1, 0);
846+
847+
ck_assert_int_eq(wolfBoot_open_image(&boot, PART_BOOT), 0);
848+
memset(&update, 0, sizeof(update));
849+
memset(&swap, 0, sizeof(swap));
850+
851+
ret = wolfBoot_delta_update(&boot, &update, &swap, 0, 0);
852+
ck_assert_int_eq(ret, -1);
853+
ck_assert_uint_eq(boot.fw_size, 0);
854+
855+
cleanup_flash();
856+
}
857+
END_TEST
858+
859+
START_TEST (test_delta_zero_size_erased_header_uses_recovery_heuristic)
860+
{
861+
struct wolfBoot_image boot, update, swap;
862+
int ret;
863+
864+
reset_mock_stats();
865+
prepare_flash();
866+
867+
ck_assert_int_eq(wolfBoot_open_image(&boot, PART_BOOT), -1);
868+
memset(&update, 0, sizeof(update));
869+
memset(&swap, 0, sizeof(swap));
870+
871+
ret = wolfBoot_delta_update(&boot, &update, &swap, 0, 0);
872+
ck_assert_int_eq(ret, -1);
873+
ck_assert_uint_eq(boot.fw_size,
874+
WOLFBOOT_PARTITION_SIZE - IMAGE_HEADER_SIZE);
875+
876+
cleanup_flash();
877+
}
878+
END_TEST
879+
#endif
820880
#endif
821881

822882

@@ -865,6 +925,7 @@ Suite *wolfboot_suite(void)
865925
TCase *invalid_update_auth_type =
866926
tcase_create("Invalid update auth type");
867927
TCase *update_toolarge = tcase_create("Update too large");
928+
TCase *zero_size_update = tcase_create("Zero size update");
868929
TCase *invalid_sha = tcase_create("Invalid SHA digest");
869930
TCase *emergency_rollback = tcase_create("Emergency rollback");
870931
TCase *emergency_rollback_failure_due_to_bad_update = tcase_create("Emergency rollback failure due to bad update");
@@ -873,6 +934,9 @@ Suite *wolfboot_suite(void)
873934
TCase *swap_resume = tcase_create("Swap resume noop");
874935
TCase *diffbase_version = tcase_create("Diffbase version lookup");
875936
TCase *boot_success = tcase_create("Boot success state");
937+
#ifdef DELTA_UPDATES
938+
TCase *delta_zero_size = tcase_create("Delta zero size");
939+
#endif
876940
#ifdef RAM_CODE
877941
TCase *self_update_sameversion = tcase_create("Self update same version erased");
878942
TCase *self_update_oldversion = tcase_create("Self update older version erased");
@@ -902,6 +966,7 @@ Suite *wolfboot_suite(void)
902966
tcase_add_test(invalid_update_type, test_invalid_update_type);
903967
tcase_add_test(invalid_update_auth_type, test_invalid_update_auth_type);
904968
tcase_add_test(update_toolarge, test_update_toolarge);
969+
tcase_add_test(zero_size_update, test_zero_size_update_rejected);
905970
tcase_add_test(invalid_sha, test_invalid_sha);
906971
tcase_add_test(emergency_rollback, test_emergency_rollback);
907972
tcase_add_test(emergency_rollback_failure_due_to_bad_update, test_emergency_rollback_failure_due_to_bad_update);
@@ -910,6 +975,10 @@ Suite *wolfboot_suite(void)
910975
tcase_add_test(swap_resume, test_swap_resume_noop);
911976
tcase_add_test(diffbase_version, test_diffbase_version_reads);
912977
tcase_add_test(boot_success, test_boot_success_sets_state);
978+
#ifdef DELTA_UPDATES
979+
tcase_add_test(delta_zero_size, test_delta_zero_size_valid_header_rejected_without_recovery_heuristic);
980+
tcase_add_test(delta_zero_size, test_delta_zero_size_erased_header_uses_recovery_heuristic);
981+
#endif
913982
#ifdef RAM_CODE
914983
tcase_add_test(self_update_sameversion, test_self_update_sameversion_erased);
915984
tcase_add_test(self_update_oldversion, test_self_update_oldversion_erased);
@@ -930,6 +999,7 @@ Suite *wolfboot_suite(void)
930999
suite_add_tcase(s, invalid_update_type);
9311000
suite_add_tcase(s, invalid_update_auth_type);
9321001
suite_add_tcase(s, update_toolarge);
1002+
suite_add_tcase(s, zero_size_update);
9331003
suite_add_tcase(s, invalid_sha);
9341004
suite_add_tcase(s, emergency_rollback);
9351005
suite_add_tcase(s, emergency_rollback_failure_due_to_bad_update);
@@ -938,6 +1008,9 @@ Suite *wolfboot_suite(void)
9381008
suite_add_tcase(s, swap_resume);
9391009
suite_add_tcase(s, diffbase_version);
9401010
suite_add_tcase(s, boot_success);
1011+
#ifdef DELTA_UPDATES
1012+
suite_add_tcase(s, delta_zero_size);
1013+
#endif
9411014
#ifdef RAM_CODE
9421015
suite_add_tcase(s, self_update_sameversion);
9431016
suite_add_tcase(s, self_update_oldversion);

0 commit comments

Comments
 (0)