diff options
author | Hung-Te Lin <hungte@chromium.org> | 2018-08-27 12:50:18 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-05 09:15:18 -0700 |
commit | 4256ddecd72ce6d2b3e7e10fbc328f57bfdc4ac6 (patch) | |
tree | e501a4c2a6781927a6101b6f5d802a6058dc1126 | |
parent | 1d4e02d8bab3f0aff945dcb6a3d828af53472b64 (diff) | |
download | vboot-4256ddecd72ce6d2b3e7e10fbc328f57bfdc4ac6.tar.gz |
futility: cmd_update: Check platform compatibility before updating
A safety check so people won't accidentally flashed wrong firmware image and
then being not able to boot.
The platform is decided by extracting the first component (delimited by dot
'.') of firmware ID. For example, platform for "Google_Link.123" is
"Google_Link".
BUG=chromium:875551
TEST=make futil; tests/futility/run_test_scripts.sh $(pwd)/build/futility
BRANCH=None
Change-Id: I90a1631f6b3e9a675fe1990cf9c204d763faf54c
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1189248
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | futility/cmd_update.c | 29 | ||||
-rwxr-xr-x | tests/futility/test_update.sh | 43 |
2 files changed, 70 insertions, 2 deletions
diff --git a/futility/cmd_update.c b/futility/cmd_update.c index 03186cd5..5639497f 100644 --- a/futility/cmd_update.c +++ b/futility/cmd_update.c @@ -900,6 +900,30 @@ static int is_write_protection_enabled(struct updater_config *cfg) return WP_ENABLED; return wp; } + +/* + * Checks if the given firmware images are compatible with current platform. + * In current implementation (following Chrome OS style), we assume the platform + * is identical to the name before a dot (.) in firmware version. + * Returns 0 for success, otherwise failure. + */ +static int check_compatible_platform(struct updater_config *cfg) +{ + int len; + struct firmware_image *image_from = &cfg->image_current, + *image_to = &cfg->image; + const char *from_dot = strchr(image_from->ro_version, '.'), + *to_dot = strchr(image_to->ro_version, '.'); + + if (!from_dot || !to_dot) { + Debug("%s: Missing dot (from=%p, to=%p)\n", from_dot, to_dot); + return -1; + } + len = from_dot - image_from->ro_version + 1; + Debug("%s: Platform: %*.*s\n", __FUNCTION__, len, len, + image_from->ro_version); + return strncmp(image_from->ro_version, image_to->ro_version, len); +} enum updater_error_codes { UPDATE_ERR_DONE, UPDATE_ERR_NEED_RO_UPDATE, @@ -908,6 +932,7 @@ enum updater_error_codes { UPDATE_ERR_INVALID_IMAGE, UPDATE_ERR_SET_COOKIES, UPDATE_ERR_WRITE_FIRMWARE, + UPDATE_ERR_PLATFORM, UPDATE_ERR_TARGET, UPDATE_ERR_UNKNOWN, }; @@ -920,6 +945,7 @@ static const char * const updater_error_messages[] = { [UPDATE_ERR_INVALID_IMAGE] = "The given firmware image is not valid.", [UPDATE_ERR_SET_COOKIES] = "Failed writing system flags to try update.", [UPDATE_ERR_WRITE_FIRMWARE] = "Failed writing firmware.", + [UPDATE_ERR_PLATFORM] = "Your system platform is not compatible.", [UPDATE_ERR_TARGET] = "No valid RW target to update. Abort.", [UPDATE_ERR_UNKNOWN] = "Unknown error.", }; @@ -1061,6 +1087,9 @@ static enum updater_error_codes update_firmware(struct updater_config *cfg) image_from->file_name, image_from->ro_version, image_from->rw_version_a, image_from->rw_version_b); + if (check_compatible_platform(cfg)) + return UPDATE_ERR_PLATFORM; + wp_enabled = is_write_protection_enabled(cfg); printf(">> Write protection: %d (%s; HW=%d, SW=%d).\n", wp_enabled, wp_enabled ? "enabled" : "disabled", diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh index 3093e25d..9a56c3da 100755 --- a/tests/futility/test_update.sh +++ b/tests/futility/test_update.sh @@ -35,6 +35,28 @@ FROM_HWID="X86 PEPPY TEST 4211" cp -f ${LINK_BIOS} ${TO_IMAGE} cp -f ${PEPPY_BIOS} ${FROM_IMAGE} +patch_file() { + local file="$1" + local section="$2" + local data="$3" + + # NAME OFFSET SIZE + local fmap_info="$(${FUTILITY} dump_fmap -p ${file} ${section})" + local offset="$(echo "${fmap_info}" | sed 's/^[^ ]* //; s/ [^ ]*$//')" + echo "offset: ${offset}" + echo -n "${data}" | dd of="${file}" bs=1 seek="${offset}" conv=notrunc +} + +# PEPPY and LINK have different platform element ("Google_Link" and +# "Google_Peppy") in firmware ID so we want to hack them by changing +# "Google_" to "Google.". +patch_file ${TO_IMAGE} RW_FWID_A Google. +patch_file ${TO_IMAGE} RW_FWID_B Google. +patch_file ${TO_IMAGE} RO_FRID Google. +patch_file ${FROM_IMAGE} RW_FWID_A Google. +patch_file ${FROM_IMAGE} RW_FWID_B Google. +patch_file ${FROM_IMAGE} RO_FRID Google. + unpack_image() { local folder="${TMP}.$1" local image="$2" @@ -75,8 +97,13 @@ test_update() { shift 3 cp -f "${emu_src}" "${TMP}.emu" echo "*** Test Item: ${test_name}" - "${FUTILITY}" update --emulate "${TMP}.emu" "$@" - cmp "${TMP}.emu" "${expected}" + if [ "${error_msg}" != "${expected}" ] && [ -n "${error_msg}" ]; then + msg="$(! "${FUTILITY}" update --emulate "${TMP}.emu" "$@" 2>&1)" + echo "${msg}" | grep -qF -- "${error_msg}" + else + "${FUTILITY}" update --emulate "${TMP}.emu" "$@" + cmp "${TMP}.emu" "${expected}" + fi } # --sys_props: mainfw_act, is_vboot2, [wp_hw, wp_sw] @@ -86,11 +113,19 @@ test_update "Full update" \ "${FROM_IMAGE}" "${TMP}.expected.full" \ -i "${TO_IMAGE}" --wp=0 +test_update "Full update (incompatible platform)" \ + "${FROM_IMAGE}" "!platform is not compatible" \ + -i "${LINK_BIOS}" --wp=0 + # Test RW-only update. test_update "RW update" \ "${FROM_IMAGE}" "${TMP}.expected.rw" \ -i "${TO_IMAGE}" --wp=1 +test_update "RW update (incompatible platform)" \ + "${FROM_IMAGE}" "!platform is not compatible" \ + -i "${LINK_BIOS}" --wp=1 + # Test Try-RW update (vboot2). test_update "RW update (A->B)" \ "${FROM_IMAGE}" "${TMP}.expected.b" \ @@ -103,6 +138,10 @@ test_update "RW update (B->A)" \ test_update "RW update -> fallback to RO+RW Full update" \ "${FROM_IMAGE}" "${TMP}.expected.full" \ -i "${TO_IMAGE}" -t --wp=0 --sys_props 1,1 +test_update "RW update (incompatible platform)" \ + "${FROM_IMAGE}" "!platform is not compatible" \ + -i "${LINK_BIOS}" -t --wp=1 + # Test Try-RW update (vboot1). test_update "RW update (vboot1, A->B)" \ |