From becfa77e5d93af4230e21720f5f2699851297cfa Mon Sep 17 00:00:00 2001 From: Tianjie Date: Wed, 5 May 2021 17:23:46 -0700 Subject: [PATCH] Support appending vbmeta digest to id/fingerprint Background in http://go/compatible-build-fingerprint. To uniquely identify the mixed build, we plan to append the unique vbmeta digest to ro.build.id. If BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT is true, the build system will not set ro.build.id. Instead, init will set it at runtime, by appending the digest to the legacy build id. Bug: 186786987 Test: build and boot a device with new build id Change-Id: Idea57df599bfd6eede760671e2555541f7dc3f21 --- init/property_service.cpp | 85 ++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/init/property_service.cpp b/init/property_service.cpp index fe3490dc6..6511bce9b 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -94,6 +94,12 @@ using android::sysprop::InitProperties::is_userspace_reboot_supported; namespace android { namespace init { +constexpr auto FINGERPRINT_PROP = "ro.build.fingerprint"; +constexpr auto LEGACY_FINGERPRINT_PROP = "ro.build.legacy.fingerprint"; +constexpr auto ID_PROP = "ro.build.id"; +constexpr auto LEGACY_ID_PROP = "ro.build.legacy.id"; +constexpr auto VBMETA_DIGEST_PROP = "ro.boot.vbmeta.digest"; +constexpr auto DIGEST_SIZE_USED = 8; static bool persistent_properties_loaded = false; @@ -857,15 +863,33 @@ static void property_initialize_ro_product_props() { } } -// If the ro.build.fingerprint property has not been set, derive it from constituent pieces -static void property_derive_build_fingerprint() { - std::string build_fingerprint = GetProperty("ro.build.fingerprint", ""); - if (!build_fingerprint.empty()) { +static void property_initialize_build_id() { + std::string build_id = GetProperty(ID_PROP, ""); + if (!build_id.empty()) { return; } + std::string legacy_build_id = GetProperty(LEGACY_ID_PROP, ""); + std::string vbmeta_digest = GetProperty(VBMETA_DIGEST_PROP, ""); + if (vbmeta_digest.size() < DIGEST_SIZE_USED) { + LOG(ERROR) << "vbmeta digest size too small " << vbmeta_digest; + // Still try to set the id field in the unexpected case. + build_id = legacy_build_id; + } else { + // Derive the ro.build.id by appending the vbmeta digest to the base value. + build_id = legacy_build_id + "." + vbmeta_digest.substr(0, DIGEST_SIZE_USED); + } + + std::string error; + auto res = PropertySet(ID_PROP, build_id, &error); + if (res != PROP_SUCCESS) { + LOG(ERROR) << "Failed to set " << ID_PROP << " to " << build_id; + } +} + +static std::string ConstructBuildFingerprint(bool legacy) { const std::string UNKNOWN = "unknown"; - build_fingerprint = GetProperty("ro.product.brand", UNKNOWN); + std::string build_fingerprint = GetProperty("ro.product.brand", UNKNOWN); build_fingerprint += '/'; build_fingerprint += GetProperty("ro.product.name", UNKNOWN); build_fingerprint += '/'; @@ -873,7 +897,10 @@ static void property_derive_build_fingerprint() { build_fingerprint += ':'; build_fingerprint += GetProperty("ro.build.version.release_or_codename", UNKNOWN); build_fingerprint += '/'; - build_fingerprint += GetProperty("ro.build.id", UNKNOWN); + + std::string build_id = + legacy ? GetProperty(LEGACY_ID_PROP, UNKNOWN) : GetProperty(ID_PROP, UNKNOWN); + build_fingerprint += build_id; build_fingerprint += '/'; build_fingerprint += GetProperty("ro.build.version.incremental", UNKNOWN); build_fingerprint += ':'; @@ -881,13 +908,49 @@ static void property_derive_build_fingerprint() { build_fingerprint += '/'; build_fingerprint += GetProperty("ro.build.tags", UNKNOWN); - LOG(INFO) << "Setting property 'ro.build.fingerprint' to '" << build_fingerprint << "'"; + return build_fingerprint; +} + +// Derive the legacy build fingerprint if we overwrite the build id at runtime. +static void property_derive_legacy_build_fingerprint() { + std::string legacy_build_fingerprint = GetProperty(LEGACY_FINGERPRINT_PROP, ""); + if (!legacy_build_fingerprint.empty()) { + return; + } + + // The device doesn't have a legacy build id, skipping the legacy fingerprint. + std::string legacy_build_id = GetProperty(LEGACY_ID_PROP, ""); + if (legacy_build_id.empty()) { + return; + } + + legacy_build_fingerprint = ConstructBuildFingerprint(true /* legacy fingerprint */); + LOG(INFO) << "Setting property '" << LEGACY_FINGERPRINT_PROP << "' to '" + << legacy_build_fingerprint << "'"; std::string error; - uint32_t res = PropertySet("ro.build.fingerprint", build_fingerprint, &error); + uint32_t res = PropertySet(LEGACY_FINGERPRINT_PROP, legacy_build_fingerprint, &error); if (res != PROP_SUCCESS) { - LOG(ERROR) << "Error setting property 'ro.build.fingerprint': err=" << res << " (" << error - << ")"; + LOG(ERROR) << "Error setting property '" << LEGACY_FINGERPRINT_PROP << "': err=" << res + << " (" << error << ")"; + } +} + +// If the ro.build.fingerprint property has not been set, derive it from constituent pieces +static void property_derive_build_fingerprint() { + std::string build_fingerprint = GetProperty("ro.build.fingerprint", ""); + if (!build_fingerprint.empty()) { + return; + } + + build_fingerprint = ConstructBuildFingerprint(false /* legacy fingerprint */); + LOG(INFO) << "Setting property '" << FINGERPRINT_PROP << "' to '" << build_fingerprint << "'"; + + std::string error; + uint32_t res = PropertySet(FINGERPRINT_PROP, build_fingerprint, &error); + if (res != PROP_SUCCESS) { + LOG(ERROR) << "Error setting property '" << FINGERPRINT_PROP << "': err=" << res << " (" + << error << ")"; } } @@ -1035,7 +1098,9 @@ void PropertyLoadBootDefaults() { } property_initialize_ro_product_props(); + property_initialize_build_id(); property_derive_build_fingerprint(); + property_derive_legacy_build_fingerprint(); property_initialize_ro_cpu_abilist(); update_sys_usb_config();