Skip to content

Commit

Permalink
Unit test for update_ram.c (wolfSSL#488)
Browse files Browse the repository at this point in the history
* Initial draft with two test cases

* Added more unit tests. Found OOB access.

* Fix potential OOB access with too-large update img

* NO_FORK disabled by default

* Cover more corner cases

* Added unit tests for update_ram.c

Fixed fallback in partition election
  • Loading branch information
danielinux authored Aug 13, 2024
1 parent 3ff7059 commit d2811b2
Show file tree
Hide file tree
Showing 5 changed files with 567 additions and 13 deletions.
30 changes: 25 additions & 5 deletions src/update_ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ int wolfBoot_ramboot(struct wolfBoot_image *img, uint8_t *src, uint8_t *dst)
#if defined(EXT_FLASH) && defined(NO_XIP)
ret = ext_flash_read((uintptr_t)src, dst, IMAGE_HEADER_SIZE);
if (ret != IMAGE_HEADER_SIZE){
wolfBoot_printf("Error reading header at %p\n", img);
wolfBoot_printf("Error reading header at %p\n", src);
return -1;
}
#else
Expand Down Expand Up @@ -111,7 +111,7 @@ int wolfBoot_ramboot(struct wolfBoot_image *img, uint8_t *src, uint8_t *dst)

void RAMFUNCTION wolfBoot_start(void)
{
int active, ret = 0;
int active = -1, ret = 0;
struct wolfBoot_image os_image;
uint8_t *image_ptr;
uint32_t *load_address = NULL;
Expand All @@ -128,7 +128,8 @@ void RAMFUNCTION wolfBoot_start(void)

for (;;) {
#ifdef WOLFBOOT_FIXED_PARTITIONS
active = wolfBoot_dualboot_candidate();
if (active < 0)
active = wolfBoot_dualboot_candidate();
if (active == PART_BOOT)
source_address = (uint32_t*)WOLFBOOT_PARTITION_BOOT_ADDRESS;
else
Expand All @@ -139,6 +140,7 @@ void RAMFUNCTION wolfBoot_start(void)
if (active < 0) { /* panic if no images available */
wolfBoot_printf("No valid image found!\n");
wolfBoot_panic();
break;
}

#ifdef WOLFBOOT_FIXED_PARTITIONS
Expand Down Expand Up @@ -185,21 +187,31 @@ void RAMFUNCTION wolfBoot_start(void)
#else
#error missing WOLFBOOT_LOAD_ADDRESS or XIP
#endif
wolfBoot_printf("Successfully selected image in part: %d\n", active);
break;
}

backup_on_failure:
wolfBoot_printf("Failure %d: Part %d, Hdr %d, Hash %d, Sig %d\n", ret,
active, os_image.hdr_ok, os_image.sha_ok, os_image.signature_ok);
/* panic if authentication fails and no backup */
if (!wolfBoot_fallback_is_possible())
if (!wolfBoot_fallback_is_possible()) {
wolfBoot_printf("Impossible recovery with fallback.\n");
wolfBoot_panic();
else {
break;
} else {
/* Invalidate failing image and switch to the other partition */
active ^= 1;
wolfBoot_printf("Active is now: %d\n", active);
continue;
}
}
#ifdef UNIT_TEST
if (wolfBoot_panicked != 0) {
wolfBoot_printf("panic!\n");
return;
}
#endif

wolfBoot_printf("Firmware Valid\n");

Expand All @@ -210,9 +222,17 @@ void RAMFUNCTION wolfBoot_start(void)
if ((wolfBoot_get_partition_state(active, &p_state) == 0) &&
(p_state == IMG_STATE_UPDATING))
{
#ifdef EXT_FLASH
ext_flash_unlock();
#else
hal_flash_unlock();
#endif
wolfBoot_set_partition_state(active, IMG_STATE_TESTING);
#ifdef EXT_FLASH
ext_flash_lock();
#else
hal_flash_lock();
#endif
}
#endif

Expand Down
9 changes: 8 additions & 1 deletion tools/unit-tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ WOLFCRYPT=../../lib/wolfssl/

TESTS:=unit-parser unit-extflash unit-aes128 unit-aes256 unit-chacha20 unit-pci \
unit-mock-state unit-sectorflags unit-image unit-nvm unit-nvm-flagshome \
unit-enc-nvm unit-enc-nvm-flagshome unit-delta unit-update-flash
unit-enc-nvm unit-enc-nvm-flagshome unit-delta unit-update-flash \
unit-update-ram

all: $(TESTS)

Expand Down Expand Up @@ -58,6 +59,9 @@ unit-enc-nvm-flagshome:WOLFCRYPT_SRC+=$(WOLFCRYPT)/wolfcrypt/src/chacha.c
unit-delta:CFLAGS+=-DNVM_FLASH_WRITEONCE -DMOCK_PARTITIONS -DDELTA_UPDATES -DDELTA_BLOCK_SIZE=512
unit-update-flash:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT -DPART_SWAP_EXT
unit-update-ram:CFLAGS+=-DMOCK_PARTITIONS -DWOLFBOOT_NO_SIGN -DUNIT_TEST_AUTH \
-DWOLFBOOT_HASH_SHA256 -DPRINTF_ENABLED -DEXT_FLASH -DPART_UPDATE_EXT \
-DPART_SWAP_EXT -DPART_BOOT_EXT -DWOLFBOOT_DUALBOOT -DNO_XIP



Expand Down Expand Up @@ -117,6 +121,9 @@ unit-delta: ../../include/target.h unit-delta.c
unit-update-flash: ../../include/target.h unit-update-flash.c
gcc -o $@ unit-update-flash.c ../../src/image.c ../../lib/wolfssl/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)

unit-update-ram: ../../include/target.h unit-update-ram.c
gcc -o $@ unit-update-ram.c ../../src/image.c ../../lib/wolfssl/wolfcrypt/src/sha256.c $(CFLAGS) $(LDFLAGS)

%.o:%.c
gcc -c -o $@ $^ $(CFLAGS)

Expand Down
10 changes: 5 additions & 5 deletions tools/unit-tests/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@

#ifdef MOCK_PARTITIONS
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0xCD000000
#define WOLFBOOT_PARTITION_SIZE 0x8000
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0xCC000000
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0xCE000000
#ifdef NO_XIP
#define WOLFBOOT_PARTITION_SIZE 0x7F00
#else
#define WOLFBOOT_PARTITION_SIZE 0x8000
#endif
#else

#ifdef WOLFBOOT_FIXED_PARTITIONS
Expand Down Expand Up @@ -70,10 +74,6 @@

#endif /* WOLFBOOT_FIXED_PARTITIONS */

/* Load address in RAM for staged OS (update_ram only) */
#define WOLFBOOT_LOAD_ADDRESS 0x200000
#define WOLFBOOT_LOAD_DTS_ADDRESS 0x400000
#endif /* MOCK_PARTITIONS */


#endif /* !H_TARGETS_TARGET_ */
17 changes: 15 additions & 2 deletions tools/unit-tests/unit-mock-flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ void hal_prepare_boot(void)

int ext_flash_erase(uintptr_t address, int len)
{
#ifdef PART_BOOT_EXT
if ((address >= WOLFBOOT_PARTITION_BOOT_ADDRESS) &&
(address < WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE)) {
erased_update++;
memset(address, 0xFF, len);
if (address >= WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE - WOLFBOOT_SECTOR_SIZE) {
erased_nvm_bank0++;
} else if (address >= WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE - 2 * WOLFBOOT_SECTOR_SIZE) {
erased_nvm_bank1++;
}
} else
#endif
if ((address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS) &&
(address < WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE)) {
erased_update++;
Expand All @@ -137,7 +149,7 @@ int ext_flash_erase(uintptr_t address, int len)
erased_swap++;
memset(address, 0xFF, len);
} else {
fail("Invalid address\n");
fail("Invalid address: %p\n", address);
return -1;
}
return 0;
Expand All @@ -161,7 +173,7 @@ int ext_flash_read(uintptr_t address, uint8_t *data, int len)
for (i = 0; i < len; i++) {
data[i] = a[i];
}
return 0;
return len;
}

void ext_flash_unlock(void)
Expand All @@ -175,6 +187,7 @@ void ext_flash_lock(void)
ext_locked++;
}


/* A simple mock memory */
static int mmap_file(const char *path, uint8_t *address, uint32_t len,
uint8_t** ret_address)
Expand Down
Loading

0 comments on commit d2811b2

Please sign in to comment.