diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2018-07-06 18:06:05 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-07-10 23:45:51 -0700 |
commit | e0abbbb5f8bd54ac7586df334979e7cd57df7802 (patch) | |
tree | c2e40d583db965c88809184eccb35625a53366eb /common | |
parent | 8757ee93e732dd49f50a4016b16f926857ab7e02 (diff) | |
download | chrome-ec-e0abbbb5f8bd54ac7586df334979e7cd57df7802.tar.gz |
rollback: Ensure rollback_update writes blocks of correct size
flash_write (rightfully) fails if the size of not a multiple of
CONFIG_FLASH_WRITE_SIZE.
BRANCH=none
BUG=b:111190988
TEST=rollbackupdate works on both whiskers and nocturne_fp
Change-Id: I8e0b1f59b06d33f4171b6e09af94a5b7a60acc61
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1127803
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Reviewed-by: Louis Collard <louiscollard@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/rollback.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/common/rollback.c b/common/rollback.c index 1b2962fc5a..590c1224af 100644 --- a/common/rollback.c +++ b/common/rollback.c @@ -209,14 +209,25 @@ BUILD_ASSERT(SHA256_DIGEST_SIZE == CONFIG_ROLLBACK_SECRET_SIZE); static int rollback_update(int32_t next_min_version, uint8_t *entropy, unsigned int length) { - struct rollback_data data; + /* + * When doing flash_write operation, the data needs to be in blocks + * of CONFIG_FLASH_WRITE_SIZE, pad rollback_data as required. + */ + uint8_t block[CONFIG_FLASH_WRITE_SIZE * + DIV_ROUND_UP(sizeof(struct rollback_data), + CONFIG_FLASH_WRITE_SIZE)]; + struct rollback_data *data = (struct rollback_data *)block; + BUILD_ASSERT(sizeof(block) >= sizeof(*data)); uintptr_t offset; int region; if (flash_get_protect() & EC_FLASH_PROTECT_ROLLBACK_NOW) return EC_ERROR_ACCESS_DENIED; - region = get_latest_rollback(&data); + /* Initialize the rest of the block. */ + memset(&block[sizeof(*data)], 0xff, sizeof(block)-sizeof(*data)); + + region = get_latest_rollback(data); if (region < 0) return EC_ERROR_UNKNOWN; @@ -224,17 +235,17 @@ static int rollback_update(int32_t next_min_version, #ifdef CONFIG_ROLLBACK_SECRET_SIZE if (entropy) { /* Do not accept to decrease the value. */ - if (next_min_version < data.rollback_min_version) - next_min_version = data.rollback_min_version; + if (next_min_version < data->rollback_min_version) + next_min_version = data->rollback_min_version; } else #endif { /* Do not accept to decrease the value. */ - if (next_min_version < data.rollback_min_version) + if (next_min_version < data->rollback_min_version) return EC_ERROR_INVAL; /* No need to update if version is already correct. */ - if (next_min_version == data.rollback_min_version) + if (next_min_version == data->rollback_min_version) return EC_SUCCESS; } @@ -243,19 +254,19 @@ static int rollback_update(int32_t next_min_version, offset = get_rollback_offset(region); - data.id = data.id + 1; - data.rollback_min_version = next_min_version; + data->id = data->id + 1; + data->rollback_min_version = next_min_version; #ifdef CONFIG_ROLLBACK_SECRET_SIZE /* * If we are provided with some entropy, add it to secret. Otherwise, * data.secret is left untouched and written back to the other region. */ if (entropy) { - if (!add_entropy(data.secret, data.secret, entropy, length)) + if (!add_entropy(data->secret, data->secret, entropy, length)) return EC_ERROR_UNCHANGED; } #endif - data.cookie = CROS_EC_ROLLBACK_COOKIE; + data->cookie = CROS_EC_ROLLBACK_COOKIE; /* Offset should never be part of active image. */ if (system_unsafe_to_overwrite(offset, CONFIG_FLASH_ERASE_SIZE)) @@ -264,7 +275,7 @@ static int rollback_update(int32_t next_min_version, if (flash_erase(offset, CONFIG_FLASH_ERASE_SIZE)) return EC_ERROR_UNKNOWN; - if (flash_write(offset, sizeof(data), (char *)&data)) + if (flash_write(offset, sizeof(block), block)) return EC_ERROR_UNKNOWN; return EC_SUCCESS; |