mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-11 10:25:20 +00:00
rwsig/update_fw: Prevent race in rollback protection
There is a window where the rollback information in RW could
potentially be updated during RW signature verification. We make
sure this cannot happen by:
- Preventing update over USB while RWSIG is running
- When system is locked, only update rollback information if
RW region is locked: this guarantees that RW cannot be modified
from boot until RW is validated, and then until rollback
information is updated.
Also, remove rollback_lock() in rwsig_check_signature:
rwsig_jump_now() protects all flash, which also protects rollback.
This reduces the number of required reboots on rollback update.
BRANCH=none
BUG=b:35586219
BUG=b:35587171
TEST=Add long delay in rwsig_check_signature, make sure EC cannot
be updated while verification is in progress.
Change-Id: I7a51fad8a64b7e258b3a7e15d75b3dab64ce1c94
Reviewed-on: https://chromium-review.googlesource.com/479176
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
758fc8f45b
commit
a04a310913
@@ -185,8 +185,13 @@ int rwsig_check_signature(void)
|
||||
/*
|
||||
* Signature verified: we know that rw_rollback_version is valid, check
|
||||
* if rollback information should be updated.
|
||||
*
|
||||
* When system is locked, we only increment the rollback if RW is
|
||||
* currently protected.
|
||||
*/
|
||||
if (rw_rollback_version != min_rollback_version) {
|
||||
if (rw_rollback_version != min_rollback_version &&
|
||||
((!system_is_locked() ||
|
||||
flash_get_protect() & EC_FLASH_PROTECT_RW_NOW))) {
|
||||
/*
|
||||
* This will fail if the rollback block is protected (RW image
|
||||
* will unprotect that block later on).
|
||||
@@ -201,12 +206,6 @@ int rwsig_check_signature(void)
|
||||
good = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock the ROLLBACK region, this will cause the board to reboot if the
|
||||
* region is not already protected.
|
||||
*/
|
||||
rollback_lock();
|
||||
#endif
|
||||
out:
|
||||
CPRINTS("RW verify %s", good ? "OK" : "FAILED");
|
||||
|
||||
@@ -145,6 +145,14 @@ void fw_update_start(struct first_response_pdu *rpdu)
|
||||
vb21_key = (const struct vb21_packed_key *)CONFIG_RO_PUBKEY_ADDR;
|
||||
rpdu->common.key_version = htobe32(vb21_key->key_version);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_TASK_RWSIG
|
||||
/* Do not allow the update to start if RWSIG is still running. */
|
||||
if (rwsig_get_status() == RWSIG_IN_PROGRESS) {
|
||||
CPRINTF("RWSIG in progress\n");
|
||||
rpdu->return_value = htobe32(UPDATE_RWSIG_BUSY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void fw_update_command_handler(void *body,
|
||||
|
||||
@@ -185,6 +185,7 @@ enum {
|
||||
UPDATE_MALLOC_ERROR = 7,
|
||||
UPDATE_ROLLBACK_ERROR = 8,
|
||||
UPDATE_RATE_LIMIT_ERROR = 9,
|
||||
UPDATE_RWSIG_BUSY = 10,
|
||||
};
|
||||
|
||||
#endif /* ! __CROS_EC_UPDATE_FW_H */
|
||||
|
||||
Reference in New Issue
Block a user