verify: enforce format transitions

When using verify's -m option, it generally only makes sense to verify a
build within the same format, since the subsequent format (if any) might
not be compatible. Therefore, we should disallow verifying to a build
with a different format by default. This commit adds the proper
enforcement by making this condition a fatal error. The early exit can
be bypassed using the -x/--force option, which will print a warning
message instead.

For now, this compatibility check is targeting the use case of verifying
to a newer build, so I also report the latest supported build for the
current format. Verifying to an older build is not guaranteed to succeed
at present, and swupd-client does not yet understand the
version/formatN/first file. In other words, reporting to the user the
oldest build they can verify to will be a future improvement.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
This commit is contained in:
Patrick McCarty
2017-08-30 11:12:50 -07:00
committed by Matthew Johnson
parent b682263c96
commit e6cdcf8aa1
3 changed files with 43 additions and 0 deletions
+1
View File
@@ -331,6 +331,7 @@ extern struct list *files_from_bundles(struct list *bundles);
extern bool version_files_consistent(void);
extern bool string_in_list(char *string_to_check, struct list *list_to_check);
extern void print_progress(unsigned int count, unsigned int max);
extern bool is_compatible_format(int format_num);
/* subscription.c */
struct list *free_list_file(struct list *item);
+25
View File
@@ -965,3 +965,28 @@ void print_progress(unsigned int count, unsigned int max)
}
}
}
/* Compare formats of the global variable (format_string) and the format number
* from a manifest (usually a MoM). Because "staging" is treated specially and
* never appears in a manifest, it is skipped. */
bool is_compatible_format(int format_num)
{
if (strcmp(format_string, "staging") == 0) {
return true;
}
char *format_manifest = NULL;
string_or_die(&format_manifest, "%d", format_num);
size_t len = strlen(format_string);
bool ret;
if (strncmp(format_string, format_manifest, len) == 0) {
ret = true;
} else {
ret = false;
}
free(format_manifest);
return ret;
}
+17
View File
@@ -702,6 +702,23 @@ int verify_main(int argc, char **argv)
goto clean_and_exit;
}
if (!is_compatible_format(official_manifest->manifest_version)) {
if (force) {
fprintf(stderr, "WARNING: the force option is specified; ignoring"
" format mismatch for verify\n");
} else {
fprintf(stderr, "ERROR: Mismatching formats detected when verifying %d"
" (expected: %s; actual: %d)\n",
version, format_string, official_manifest->manifest_version);
int latest = get_latest_version();
if (latest > 0) {
fprintf(stderr, "Latest supported version to verify: %d\n", latest);
}
ret = EMANIFEST_LOAD;
goto clean_and_exit;
}
}
ret = add_included_manifests(official_manifest, version, &subs);
if (ret) {
ret = EMANIFEST_LOAD;