summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2017-09-05 11:39:01 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-09-14 16:56:20 +0000
commit17b786ded098cfb9aeed9ae92af1122039e07df1 (patch)
tree8d97034b2604423abecea4e1ca5481a99f7d8de3
parent91ba537523005236e7a7df33ce659f9c46f4e4d4 (diff)
downloadchrome-ec-17b786ded098cfb9aeed9ae92af1122039e07df1.tar.gz
cr50 updater: reject images with mismatching board ID
There is no point in updating the Cr50 to an image which will not be allowed to run due to board ID settings mismatch. This patch modifies the prototype of check_board_id_mismatch() to allow to pass to this function an arbitrary pointer to an image header, so that the function can check not only the image in the flash memory, but also the image which just arrived over the line. The contents_allowed() function now checks if the new image is compatible with the Board ID value in Info1 and rejects the new image if there is a mismatch. BRANCH=cr50 BUG=none TEST=tried updating a Cr50 to an image which is incompatible with the Info1 fields contents. The update attempt is rejected. Verified that updating to a compatible image still works as designed. Change-Id: I3d6c16df11fcabd05888f3cbf5e9a81dc51fe66f Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/650812 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org> (cherry picked from commit 8e6d0fb64ab5f78557b2725dbc399603ec579631) Reviewed-on: https://chromium-review.googlesource.com/656424 (cherry picked from commit 930e7036473f4094a2a4c22cab2fae69f35877cf) Reviewed-on: https://chromium-review.googlesource.com/666536
-rw-r--r--board/cr50/board.c2
-rw-r--r--chip/g/board_id.c8
-rw-r--r--chip/g/board_id.h7
-rw-r--r--chip/g/upgrade_fw.c14
-rw-r--r--chip/g/upgrade_fw.h1
5 files changed, 23 insertions, 9 deletions
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 8cc0970586..48dcbfa492 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -558,7 +558,7 @@ int board_id_is_mismatched(void)
static void check_board_id_mismatch(void)
{
- if (!board_id_mismatch())
+ if (!board_id_mismatch(NULL))
return;
if (system_rollback_detected()) {
diff --git a/chip/g/board_id.c b/chip/g/board_id.c
index 85b84c63ed..ac47d973be 100644
--- a/chip/g/board_id.c
+++ b/chip/g/board_id.c
@@ -94,13 +94,13 @@ int read_board_id(struct board_id *id)
return EC_SUCCESS;
}
-uint32_t board_id_mismatch(void)
+uint32_t board_id_mismatch(const struct SignedHeader *sh)
{
struct board_id id;
- const struct SignedHeader *sh;
- /* Get header of the currently running image. */
- sh = get_current_image_header();
+ if (!sh)
+ /* Get header of the currently running image. */
+ sh = get_current_image_header();
/* Get Board ID from INFO1. */
if (read_board_id(&id) != EC_SUCCESS)
diff --git a/chip/g/board_id.h b/chip/g/board_id.h
index 90633fa309..6aa106d5b0 100644
--- a/chip/g/board_id.h
+++ b/chip/g/board_id.h
@@ -47,11 +47,14 @@ uint32_t check_board_id_vs_header(const struct board_id *id,
int read_board_id(struct board_id *id);
/**
- * Check if board ID in the current image matches board ID field in the INFO1.
+ * Check if board ID in the image matches board ID field in the INFO1.
+ *
+ * Pass the pointer to the image header to check. If the pointer is set to
+ * NULL, check board ID against the currently running image's header.
*
* Return true if there is a mismatch (the code should not run).
*/
-uint32_t board_id_mismatch(void);
+uint32_t board_id_mismatch(const struct SignedHeader *h);
BUILD_ASSERT((offsetof(struct info1_board_space, bid) & 3) == 0);
BUILD_ASSERT((INFO_BOARD_ID_SIZE & 3) == 0);
diff --git a/chip/g/upgrade_fw.c b/chip/g/upgrade_fw.c
index e2acd92203..6f6ed24d38 100644
--- a/chip/g/upgrade_fw.c
+++ b/chip/g/upgrade_fw.c
@@ -5,6 +5,7 @@
#include "config.h"
+#include "board_id.h"
#include "byteorder.h"
#include "compile_time_macros.h"
#include "console.h"
@@ -178,8 +179,9 @@ static int new_is_older(const struct SignedHeader *new,
}
/*
- * Check if this chunk of data is a rollback attempt, or is unaligned, or
- * overlaps RO or RW header.
+ * Check if this chunk of data is a rollback attempt, or is unaligned,
+ * overlaps RO or RW header, or would cause a board ID mismatch if attempted
+ * to run.
*
* Return False if there is any of the above problems and set the passed in
* error_code pointer to the proper error_code.
@@ -190,6 +192,7 @@ static int contents_allowed(uint32_t block_offset,
{
/* Pointer to RO or RW header in flash, to compare against. */
const struct SignedHeader *header;
+ int is_rw_header = 0;
if (block_offset == valid_sections.ro_base_offset) {
header = (const struct SignedHeader *)
@@ -197,6 +200,7 @@ static int contents_allowed(uint32_t block_offset,
} else if (block_offset == valid_sections.rw_base_offset) {
header = (const struct SignedHeader *)
get_program_memory_addr(system_get_image_copy());
+ is_rw_header = 1;
} else {
/*
@@ -245,6 +249,12 @@ static int contents_allowed(uint32_t block_offset,
return 0;
}
+ if (is_rw_header && board_id_mismatch(upgrade_data)) {
+ CPRINTF("%s: rejecting Board ID mismatch.\n", __func__);
+ *error_code = UPGRADE_BOARD_ID_ERROR;
+ return 0;
+ }
+
return 1;
}
diff --git a/chip/g/upgrade_fw.h b/chip/g/upgrade_fw.h
index 11de5d52f0..177793407c 100644
--- a/chip/g/upgrade_fw.h
+++ b/chip/g/upgrade_fw.h
@@ -140,6 +140,7 @@ enum return_value {
UPGRADE_RATE_LIMIT_ERROR = 9,
UPGRADE_UNALIGNED_BLOCK_ERROR = 10,
UPGRADE_TRUNCATED_HEADER_ERROR = 11,
+ UPGRADE_BOARD_ID_ERROR = 12,
};
/*