summaryrefslogtreecommitdiff
path: root/futility/updater_utils.c
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2020-02-17 16:02:08 +0800
committerCommit Bot <commit-bot@chromium.org>2020-02-21 10:35:48 +0000
commitb2efcbe10010944d0ed6c49e2131d898ee7ea7fe (patch)
tree4619477c0e2efcff20bc8d0387f24a3ee1e2fb4d /futility/updater_utils.c
parent83ab1908e8173cddc8405a341fe1dc79a2c8d911 (diff)
downloadvboot-b2efcbe10010944d0ed6c49e2131d898ee7ea7fe.tar.gz
futility: updater: Ignore image parsing error in --force
The firmware updater has been improved to support flashing outside DUT (--ccd, --servo) that also implies more people will use it for devices with corrupted (or empty) firmware. It's pretty confusing for developers to see "Cannot load system active firmware" while the flashrom can actually read and write to the SPI firmware. The solution here is to allow updating on such devices when --force is specified (which is automatically applied for --servo and --ccd). BUG=b:148405957 TEST=make runtests BRANCH=None Change-Id: I19e63e3464616bc508639cbfad0d1cf8e99507b0 Signed-off-by: Hung-Te Lin <hungte@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2059621 Reviewed-by: Joel Kitching <kitching@chromium.org>
Diffstat (limited to 'futility/updater_utils.c')
-rw-r--r--futility/updater_utils.c89
1 files changed, 55 insertions, 34 deletions
diff --git a/futility/updater_utils.c b/futility/updater_utils.c
index 4a91a05f..fadfd04b 100644
--- a/futility/updater_utils.c
+++ b/futility/updater_utils.c
@@ -130,84 +130,105 @@ const char *cbfs_extract_file(const char *image_file,
/*
* Loads the firmware information from an FMAP section in loaded firmware image.
* The section should only contain ASCIIZ string as firmware version.
- * If successful, the return value is zero and *version points to a newly
- * allocated string as firmware version (caller must free it); otherwise
- * failure.
+ * Returns 0 if a non-empty version string is stored in *version, otherwise -1.
*/
static int load_firmware_version(struct firmware_image *image,
const char *section_name,
char **version)
{
struct firmware_section fwid;
- find_firmware_section(&fwid, image, section_name);
- if (fwid.size) {
- *version = strndup((const char*)fwid.data, fwid.size);
- /*
- * For 'system current' images, the version string may contain
- * invalid characters that we do want to strip.
- */
- strip_string(*version, "\xff");
- return 0;
+ int len = 0;
+
+ /*
+ * section_name is NULL when parsing the RW versions on a non-vboot
+ * image (and already warned in load_firmware_image). We still need to
+ * initialize *version with empty string.
+ */
+ if (section_name) {
+ find_firmware_section(&fwid, image, section_name);
+ if (fwid.size)
+ len = fwid.size;
+ else
+ WARN("No valid section '%s', missing version info.\n",
+ section_name);
+ }
+
+ if (!len) {
+ *version = strdup("");
+ return -1;
}
- *version = strdup("");
- return -1;
+
+ /*
+ * For 'system current' images, the version string may contain
+ * invalid characters that we do want to strip.
+ */
+ *version = strndup((const char *)fwid.data, len);
+ strip_string(*version, "\xff");
+ return 0;
}
/*
* Loads a firmware image from file.
* If archive is provided and file_name is a relative path, read the file from
* archive.
- * Returns 0 on success, otherwise failure.
+ * Returns IMAGE_LOAD_SUCCESS on success, IMAGE_READ_FAILURE on file I/O
+ * failure, or IMAGE_PARSE_FAILURE for non-vboot images.
*/
int load_firmware_image(struct firmware_image *image, const char *file_name,
struct archive *archive)
{
+ int ret = IMAGE_LOAD_SUCCESS;
+ const char *section_a = NULL, *section_b = NULL;
+
if (!file_name) {
ERROR("No file name given\n");
- return -1;
+ return IMAGE_READ_FAILURE;
}
VB2_DEBUG("Load image file from %s...\n", file_name);
if (!archive_has_entry(archive, file_name)) {
ERROR("Does not exist: %s\n", file_name);
- return -1;
+ return IMAGE_READ_FAILURE;
}
if (archive_read_file(archive, file_name, &image->data, &image->size,
NULL) != VB2_SUCCESS) {
ERROR("Failed to load %s\n", file_name);
- return -1;
+ return IMAGE_READ_FAILURE;
}
VB2_DEBUG("Image size: %d\n", image->size);
assert(image->data);
image->file_name = strdup(file_name);
-
image->fmap_header = fmap_find(image->data, image->size);
+
if (!image->fmap_header) {
ERROR("Invalid image file (missing FMAP): %s\n", file_name);
- return -1;
+ ret = IMAGE_PARSE_FAILURE;
}
- if (!firmware_section_exists(image, FMAP_RO_FRID)) {
- ERROR("Does not look like VBoot firmware image: %s\n",
- file_name);
- return -1;
- }
+ if (load_firmware_version(image, FMAP_RO_FRID, &image->ro_version))
+ ret = IMAGE_PARSE_FAILURE;
- load_firmware_version(image, FMAP_RO_FRID, &image->ro_version);
if (firmware_section_exists(image, FMAP_RW_FWID_A)) {
- char **a = &image->rw_version_a, **b = &image->rw_version_b;
- load_firmware_version(image, FMAP_RW_FWID_A, a);
- load_firmware_version(image, FMAP_RW_FWID_B, b);
+ section_a = FMAP_RW_FWID_A;
+ section_b = FMAP_RW_FWID_B;
} else if (firmware_section_exists(image, FMAP_RW_FWID)) {
- char **a = &image->rw_version_a, **b = &image->rw_version_b;
- load_firmware_version(image, FMAP_RW_FWID, a);
- load_firmware_version(image, FMAP_RW_FWID, b);
- } else {
+ section_a = FMAP_RW_FWID;
+ section_b = FMAP_RW_FWID;
+ } else if (!ret) {
ERROR("Unsupported VBoot firmware (no RW ID): %s\n", file_name);
+ ret = IMAGE_PARSE_FAILURE;
}
- return 0;
+
+ /*
+ * Load and initialize both RW A and B sections.
+ * Note some unit tests will create only RW A.
+ */
+ load_firmware_version(image, section_a, &image->rw_version_a);
+ load_firmware_version(image, section_b, &image->rw_version_b);
+
+ return ret;
}
/*