summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJett Rink <jettrink@google.com>2022-05-20 16:36:00 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-05-23 20:38:18 +0000
commitd5c58ca5b9cd910544c775e7d3617e68736ecf6a (patch)
treed50a7616bc18a38e59673cba81ba6a54ba60d1b6
parentca0511abb2d6b03539eab8835426d5bad9a65216 (diff)
downloadchrome-ec-d5c58ca5b9cd910544c775e7d3617e68736ecf6a.tar.gz
gsctool: block ti50 upgrade without going through 0.0.15
We need to ensure that versions before 0.0.15 upgrade to 0.0.15 before going to 0.0.16 or later. Otherwise, the first page of the new RW is erased when upgrading RO and we need to rescue. BUG=none TEST=locally changed must have version to 0.22.0 and played around with different versions on my brya. Worked as expected around version 0.22.0 Change-Id: I79b41fb86c22aa37163264815faef9558370d702 Signed-off-by: Jett Rink <jettrink@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3658243 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Tested-by: Jett Rink <jettrink@chromium.org> Commit-Queue: Vadim Bendebury <vbendeb@chromium.org> Commit-Queue: Jett Rink <jettrink@chromium.org> Auto-Submit: Jett Rink <jettrink@chromium.org>
-rw-r--r--extra/usb_updater/gsctool.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c
index f170c1d73a..e57e9ba196 100644
--- a/extra/usb_updater/gsctool.c
+++ b/extra/usb_updater/gsctool.c
@@ -1120,8 +1120,8 @@ static void fetch_header_versions(const void *image)
/* Compare to signer headers and determine which one is newer. */
-static int a_newer_than_b(struct signed_header_version *a,
- struct signed_header_version *b)
+static int a_newer_than_b(const struct signed_header_version *a,
+ const struct signed_header_version *b)
{
uint32_t fields[][3] = {
{a->epoch, a->major, a->minor},
@@ -1152,6 +1152,32 @@ static int a_newer_than_b(struct signed_header_version *a,
return 0; /* All else being equal A is no newer than B. */
}
+
+/*
+ * Determine if the current RW version can be upgrade to the potential RW
+ * version. If not, will exit the program.
+ */
+static void check_rw_upgrade(const struct signed_header_version *current_rw,
+ const struct signed_header_version *to_rw)
+{
+ /*
+ * Disallow upgrade to 0.0.16+ without going through 0.0.15
+ * first. This check won't be needed after 2023-01-01
+ */
+ const struct signed_header_version ver15 = { .epoch = 0,
+ .major = 0,
+ .minor = 15 };
+ const int current_less_than_15 = a_newer_than_b(&ver15, current_rw);
+ const int to_greater_than_15 = a_newer_than_b(to_rw, &ver15);
+
+ if (image_magic == MAGIC_DAUNTLESS && current_less_than_15 &&
+ to_greater_than_15) {
+ printf("Must upgrade to RW 0.0.15 first!\n");
+ /* Do not continue with any upgrades RW or RO */
+ exit(update_error);
+ }
+}
+
/*
* Pick sections to transfer based on information retrieved from the target,
* the new image, and the protocol version the target is running.
@@ -1180,8 +1206,12 @@ static void pick_sections(struct transfer_descriptor *td)
*/
if (a_newer_than_b(&sections[i].shv, &targ.shv[1]) ||
- !td->upstart_mode)
+ !td->upstart_mode) {
+ /* Check will exit if disallowed */
+ check_rw_upgrade(&targ.shv[1],
+ &sections[i].shv);
sections[i].ustatus = needed;
+ }
/* Rest of loop is RO */
continue;
}