summaryrefslogtreecommitdiff
path: root/common/rollback.c
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-07-06 18:06:05 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-07-10 23:45:51 -0700
commite0abbbb5f8bd54ac7586df334979e7cd57df7802 (patch)
treec2e40d583db965c88809184eccb35625a53366eb /common/rollback.c
parent8757ee93e732dd49f50a4016b16f926857ab7e02 (diff)
downloadchrome-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/rollback.c')
-rw-r--r--common/rollback.c33
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;