diff options
-rw-r--r-- | chip/g/system.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/chip/g/system.c b/chip/g/system.c index d68da094f2..2e464391db 100644 --- a/chip/g/system.c +++ b/chip/g/system.c @@ -610,6 +610,8 @@ static void update_rollback_mask(uint32_t addr_a, uint32_t addr_b, #ifndef CR50_DEV const struct SignedHeader *header_a; const struct SignedHeader *header_b; + const struct SignedHeader *header_this; + int updated_words_count = 0; int i; int write_enabled = 0; @@ -630,6 +632,29 @@ static void update_rollback_mask(uint32_t addr_a, uint32_t addr_b, * (where those bits in the header are not zeroed) will fail, thus * ensuring rollback protection. */ + /* + * Due to build system quirks this code could creep in even into + * images which have all rollback bits in the header set to zero + * (usually such images are built with CR50_DEV=1). Let's explicitly + * check that the current running image does not have the rollback + * space completely zeroed. + * + * Note that this function is invoked to update both RO and RW INFO1 + * rollback masks, but here we care only about the RW case, since we + * never build RO images with fully erased rollback map. + */ + header_this = (const struct SignedHeader *) + get_program_memory_addr(system_get_image_copy()); + if ((header_this == header_a) || (header_this == header_b)) { + for (i = 0; i < ARRAY_SIZE(header_this->infomap); i++) { + if (header_this->infomap[i]) + break; + } + if (i == ARRAY_SIZE(header_this->infomap)) { + CPRINTS("Skipped updating INFO1 RW map"); + return; + } + } /* For each bit in the header infomap field of the running image. */ for (i = 0; i < INFO_MAX; i++) { uint32_t bit; |