diff options
-rw-r--r-- | futility/updater.c | 11 | ||||
-rw-r--r-- | futility/updater.h | 10 | ||||
-rw-r--r-- | futility/updater_quirks.c | 49 | ||||
-rwxr-xr-x | tests/futility/test_update.sh | 12 |
4 files changed, 75 insertions, 7 deletions
diff --git a/futility/updater.c b/futility/updater.c index fd13bb8b..71a498e3 100644 --- a/futility/updater.c +++ b/futility/updater.c @@ -1288,10 +1288,15 @@ static int updater_setup_quirks(struct updater_config *cfg, const struct updater_config_arguments *arg) { int errorcnt = 0; - const char *quirks = updater_get_default_quirks(cfg); + const char *model_quirks = updater_get_model_quirks(cfg); + char *cbfs_quirks = updater_get_cbfs_quirks(cfg); - if (quirks) - errorcnt += !!setup_config_quirks(quirks, cfg); + if (model_quirks) + errorcnt += !!setup_config_quirks(model_quirks, cfg); + if (cbfs_quirks) { + errorcnt += !!setup_config_quirks(cbfs_quirks, cfg); + free(cbfs_quirks); + } if (arg->quirks) errorcnt += !!setup_config_quirks(arg->quirks, cfg); return errorcnt; diff --git a/futility/updater.h b/futility/updater.h index 3ed8039c..a4f55806 100644 --- a/futility/updater.h +++ b/futility/updater.h @@ -175,10 +175,16 @@ int get_config_quirk(enum quirk_types quirk, const struct updater_config *cfg); int get_system_property(enum system_property_type property_type, struct updater_config *cfg); /* - * Gets the default quirk config string for target image. + * Gets the default quirk config string from target image name. * Returns a string (in same format as --quirks) to load or NULL if no quirks. */ -const char * const updater_get_default_quirks(struct updater_config *cfg); +const char * const updater_get_model_quirks(struct updater_config *cfg); + +/* + * Gets the quirk config string from target image CBFS. + * Returns a string (in same format as --quirks) to load or NULL if no quirks. + */ +char * updater_get_cbfs_quirks(struct updater_config *cfg); /* * Overrides signature id if the device was shipped with known diff --git a/futility/updater_quirks.c b/futility/updater_quirks.c index e4056b05..b3dea936 100644 --- a/futility/updater_quirks.c +++ b/futility/updater_quirks.c @@ -476,10 +476,10 @@ void updater_register_quirks(struct updater_config *cfg) } /* - * Gets the default quirk config string for target image. + * Gets the default quirk config string from target image name. * Returns a string (in same format as --quirks) to load or NULL if no quirks. */ -const char * const updater_get_default_quirks(struct updater_config *cfg) +const char * const updater_get_model_quirks(struct updater_config *cfg) { const char *pattern = cfg->image.ro_version; int i; @@ -500,6 +500,51 @@ const char * const updater_get_default_quirks(struct updater_config *cfg) } /* + * Gets the quirk config string from target image CBFS. + * Returns a string (in same format as --quirks) to load or NULL if no quirks. + */ +char *updater_get_cbfs_quirks(struct updater_config *cfg) +{ + const char *entry_name = "updater_quirks"; + const char *cbfs_region = "FW_MAIN_A"; + struct firmware_section cbfs_section; + + /* Before invoking cbfstool, try to search for CBFS file name. */ + find_firmware_section(&cbfs_section, &cfg->image, cbfs_region); + if (!cbfs_section.size || !memmem(cbfs_section.data, cbfs_section.size, + entry_name, strlen(entry_name))) { + if (!cbfs_section.size) + VB2_DEBUG("Missing region: %s\n", cbfs_region); + else + VB2_DEBUG("Cannot find entry: %s\n", entry_name); + return NULL; + } + + const char *tmp_path = get_firmware_image_temp_file( + &cfg->image, &cfg->tempfiles); + uint8_t *data = NULL; + uint32_t size = 0; + + /* Although the name exists, it may not be a real file. */ + if (!cbfs_file_exists(tmp_path, cbfs_region, entry_name)) { + VB2_DEBUG("Found string '%s' but not a file.\n", entry_name); + return NULL; + } + + VB2_DEBUG("Found %s from CBFS %s\n", entry_name, cbfs_region); + tmp_path = cbfs_extract_file(tmp_path, cbfs_region, entry_name, + &cfg->tempfiles); + if (!tmp_path || + vb2_read_file(tmp_path, &data, &size) != VB2_SUCCESS) { + ERROR("Failed to read [%s] from CBFS [%s].\n", + entry_name, cbfs_region); + return NULL; + } + VB2_DEBUG("Got quirks (%u bytes): %s\n", size, data); + return (char *)data; +} + +/* * Overrides signature id if the device was shipped with known * special rootkey. */ diff --git a/tests/futility/test_update.sh b/tests/futility/test_update.sh index 655bab4a..ae4a3624 100755 --- a/tests/futility/test_update.sh +++ b/tests/futility/test_update.sh @@ -480,4 +480,16 @@ if type cbfstool >/dev/null 2>&1; then "${TMP}.from.smm" "${TMP}.expected.full_smm" \ -i "${TO_IMAGE}" --wp=0 --sys_props 0,0x10001,1 \ --quirks eve_smm_store + + echo "min_platform_version=3" >"${TMP}.quirk" + cp -f "${TO_IMAGE}" "${TO_IMAGE}.quirk" + ${FUTILITY} dump_fmap -x "${TO_IMAGE}" "BOOT_STUB:${TMP}.cbfs" + # Create a fake CBFS using FW_MAIN_A size. + truncate -s $((0x000dffc0)) "${TMP}.cbfs" + ${FUTILITY} load_fmap "${TO_IMAGE}.quirk" "FW_MAIN_A:${TMP}.cbfs" + cbfstool "${TO_IMAGE}.quirk" add -r FW_MAIN_A -n updater_quirks \ + -f "${TMP}.quirk" -t raw + test_update "Full update (failure by CBFS quirks)" \ + "${FROM_IMAGE}" "!Need platform version >= 3 (current is 2)" \ + -i "${TO_IMAGE}.quirk" --wp=0 --sys_props 0,0x10001,1,2 fi |