diff options
-rw-r--r-- | extra/usb_updater/gsctool.c | 36 |
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(§ions[i].shv, &targ.shv[1]) || - !td->upstart_mode) + !td->upstart_mode) { + /* Check will exit if disallowed */ + check_rw_upgrade(&targ.shv[1], + §ions[i].shv); sections[i].ustatus = needed; + } /* Rest of loop is RO */ continue; } |