summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2018-08-27 12:50:18 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-09-05 09:15:18 -0700
commit4256ddecd72ce6d2b3e7e10fbc328f57bfdc4ac6 (patch)
treee501a4c2a6781927a6101b6f5d802a6058dc1126
parent1d4e02d8bab3f0aff945dcb6a3d828af53472b64 (diff)
downloadvboot-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.c29
-rwxr-xr-xtests/futility/test_update.sh43
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)" \