diff --git a/.github/workflows/test-powerfail-simulator.yml b/.github/workflows/test-powerfail-simulator.yml index bdc39bcf..764960d0 100644 --- a/.github/workflows/test-powerfail-simulator.yml +++ b/.github/workflows/test-powerfail-simulator.yml @@ -137,6 +137,6 @@ jobs: make test-sim-internal-flash-with-delta-update # DELTA update currently fails when patch is large enough - #- name: Run update-revert test with power failures (DELTA) - #run: | - #tools/scripts/sim-update-powerfail-resume.sh + - name: Run update-revert test with power failures (DELTA) + run: | + tools/scripts/sim-update-powerfail-resume.sh diff --git a/src/update_flash.c b/src/update_flash.c index b4f2bf98..d9c8b803 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -371,6 +371,9 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) uint8_t key[ENCRYPT_KEY_SIZE]; uint8_t nonce[ENCRYPT_NONCE_SIZE]; #endif +#ifdef DELTA_UPDATES + uint8_t interrupted = 0; +#endif /* No Safety check on open: we might be in the middle of a broken update */ wolfBoot_open_image(&update, PART_UPDATE); @@ -392,7 +395,6 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) update_type = wolfBoot_get_image_type(PART_UPDATE); - /* Check the first sector to detect interrupted update */ if ((wolfBoot_get_update_sector_flag(0, &flag) < 0) || (flag == SECT_FLAG_NEW)) @@ -413,18 +415,25 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) (wolfBoot_current_firmware_version() < wolfBoot_update_firmware_version()) ) { VERIFY_VERSION_ALLOWED(fallback_allowed); - } else { + } else return -1; - } #endif } #ifdef DELTA_UPDATES if ((update_type & 0x00F0) == HDR_IMG_TYPE_DIFF) { + /* if the first sector flag is not new but we are updating then we */ + /* were interrupted and need to resume instead of inverting */ + if (flag != SECT_FLAG_NEW && + (wolfBoot_get_partition_state(PART_UPDATE, &st) == 0) && + (st == IMG_STATE_UPDATING)) { + interrupted = 1; + } + return wolfBoot_delta_update(&boot, &update, &swap, (wolfBoot_current_firmware_version() >= - wolfBoot_update_firmware_version())); + wolfBoot_update_firmware_version() && !interrupted)); } #endif diff --git a/tools/scripts/sim-update-powerfail-resume.sh b/tools/scripts/sim-update-powerfail-resume.sh index 18983e4d..93bf7c3f 100755 --- a/tools/scripts/sim-update-powerfail-resume.sh +++ b/tools/scripts/sim-update-powerfail-resume.sh @@ -1,12 +1,10 @@ #!/bin/bash - V=`./wolfboot.elf update_trigger get_version 2>/dev/null` if [ "x$V" != "x1" ]; then echo "Failed first boot with update_trigger" exit 1 fi - ./wolfboot.elf powerfail 15000 get_version 2>/dev/null ./wolfboot.elf powerfail 18000 get_version 2>/dev/null ./wolfboot.elf powerfail 1a000 get_version 2>/dev/null @@ -17,17 +15,5 @@ if [ "x$V" != "x2" ]; then exit 1 fi -./wolfboot.elf powerfail 11000 get_version 2>/dev/null -./wolfboot.elf powerfail 14000 get_version 2>/dev/null -./wolfboot.elf powerfail 1e000 get_version 2>/dev/null - -V=`./wolfboot.elf get_version 2>/dev/null` -if [ "x$V" != "x1" ]; then - echo "Failed fallback (V: $V)" - exit 1 -fi - echo Test successful. exit 0 - -