@@ -686,6 +686,11 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
686686 int inverse = 0 ;
687687#endif
688688 int fallback_image = 0 ;
689+ #ifndef DISABLE_BACKUP
690+ int rollback = 0 ;
691+ int bootStateRet = -1 ;
692+ uint8_t bootState = 0 ;
693+ #endif
689694#if defined(DISABLE_BACKUP ) && defined(EXT_ENCRYPTED )
690695 uint8_t key [ENCRYPT_KEY_SIZE ];
691696 uint8_t nonce [ENCRYPT_NONCE_SIZE ];
@@ -748,6 +753,13 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
748753
749754 cur_ver = wolfBoot_current_firmware_version ();
750755 upd_ver = wolfBoot_update_firmware_version ();
756+ #ifndef DISABLE_BACKUP
757+ bootStateRet = wolfBoot_get_partition_state (PART_BOOT , & bootState );
758+ if ((bootStateRet == 0 ) && (bootState == IMG_STATE_TESTING ) &&
759+ (fallback_allowed != 0 ) && (cur_ver >= upd_ver )) {
760+ rollback = 1 ;
761+ }
762+ #endif
751763
752764 wolfBoot_get_update_sector_flag (0 , & flag );
753765 /* Check the first sector to detect interrupted update */
@@ -787,9 +799,9 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
787799 cur_ver , upd_ver );
788800
789801#ifndef ALLOW_DOWNGRADE
790- if ( (( fallback_allowed == 1 ) &&
791- (~( uint32_t ) fallback_allowed == 0xFFFFFFFE )) ||
792- (cur_ver < upd_ver ) ) {
802+ if (fallback_allowed != 0 ) {
803+ /* Fallback path skips redundant version checks. */
804+ } else if (cur_ver < upd_ver ) {
793805 VERIFY_VERSION_ALLOWED (fallback_allowed );
794806 } else {
795807 wolfBoot_printf ("Update version not allowed\n" );
@@ -973,6 +985,19 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
973985 /* start re-entrant final erase, return code is only for resumption in
974986 * wolfBoot_start */
975987 wolfBoot_swap_and_final_erase (0 );
988+ #ifndef DISABLE_BACKUP
989+ if (rollback ) {
990+ hal_flash_unlock ();
991+ #ifdef EXT_FLASH
992+ ext_flash_unlock ();
993+ #endif
994+ wolfBoot_set_partition_state (PART_BOOT , IMG_STATE_SUCCESS );
995+ #ifdef EXT_FLASH
996+ ext_flash_lock ();
997+ #endif
998+ hal_flash_lock ();
999+ }
1000+ #endif
9761001#else
9771002 /* Mark boot partition as TESTING - this tells bootloader to fallback if update fails */
9781003 wolfBoot_set_partition_state (PART_BOOT , IMG_STATE_TESTING );
@@ -1201,13 +1226,27 @@ void RAMFUNCTION wolfBoot_start(void)
12011226#if !defined(DISABLE_BACKUP ) && !defined(CUSTOM_PARTITION_TRAILER )
12021227 /* resume the final erase in case the power failed before it finished */
12031228 resumedFinalErase = wolfBoot_swap_and_final_erase (1 );
1204- if (resumedFinalErase != 0 )
1229+ if ((resumedFinalErase != 0 ) ||
1230+ ((bootRet == 0 ) && (bootState == IMG_STATE_TESTING )))
12051231#endif
12061232 {
12071233 /* Check if the BOOT partition is still in TESTING,
12081234 * to trigger fallback.
12091235 */
12101236 if ((bootRet == 0 ) && (bootState == IMG_STATE_TESTING )) {
1237+ if (updateRet != 0 ) {
1238+ hal_flash_unlock ();
1239+ #ifdef EXT_FLASH
1240+ ext_flash_unlock ();
1241+ #endif
1242+ wolfBoot_set_partition_state (PART_UPDATE , IMG_STATE_UPDATING );
1243+ #ifdef EXT_FLASH
1244+ ext_flash_lock ();
1245+ #endif
1246+ hal_flash_lock ();
1247+ updateRet = 0 ;
1248+ updateState = IMG_STATE_UPDATING ;
1249+ }
12111250 wolfBoot_update (1 );
12121251 }
12131252
0 commit comments