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
This commit is contained in:
Tianjie 2021-05-05 17:23:46 -07:00 committed by Tianjie Xu
parent 362b2b7537
commit becfa77e5d

View file

@ -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();