diff options
author | Danny Lin <danny@kdrag0n.dev> | 2020-10-07 00:24:54 -0700 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2022-01-26 23:10:42 +0800 |
commit | adbb1c10dd503804988344c1905df3c23973cf0d (patch) | |
tree | d328d4a1d2c9395ca91a55e6103df8a22991398b | |
parent | 375d7503efe8553bf21384d48be54d6e946f8514 (diff) |
init: Report valid verified boot for SafetyNet checkssugisawa
Google's SafetyNet attestation includes checks for the integrity of the
verified boot chain, as reported by some ro.boot.* properties normally
passed by the bootloader. Unconditionally reporting successful, valid
values helps pass SafetyNet checks, as long as other system state is
intact.
However, the real prop values must be retained in recovery/fastbootd in
order for fastbootd to allow/deny flashing correctly based on the
bootloader lock state. This is accomplished by checking androidboot keys
in the kernel cmdline and bootconfig (necessary on Pixel 6), and not
spoofing anything if the boot isn't a normal full-blown Android boot.
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
-rw-r--r-- | init/property_service.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/init/property_service.cpp b/init/property_service.cpp index 3f71af71b..0765b3bc9 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -1336,6 +1336,7 @@ static void ProcessKernelDt() { } constexpr auto ANDROIDBOOT_PREFIX = "androidboot."sv; +constexpr auto ANDROIDBOOT_MODE = "androidboot.mode"sv; static void ProcessKernelCmdline() { ImportKernelCmdline([&](const std::string& key, const std::string& value) { @@ -1354,6 +1355,35 @@ static void ProcessBootconfig() { }); } +static void SetSafetyNetProps() { + // Check whether this is a normal boot, and whether the bootloader is actually locked + auto isNormalBoot = true; // no prop = normal boot + // This runs before keys are set as props, so we need to process them ourselves. + ImportKernelCmdline([&](const std::string& key, const std::string& value) { + if (key == ANDROIDBOOT_MODE && value != "normal") { + isNormalBoot = false; + } + }); + ImportBootconfig([&](const std::string& key, const std::string& value) { + if (key == ANDROIDBOOT_MODE && value != "normal") { + isNormalBoot = false; + } + }); + + // Bail out if this is recovery, fastbootd, or anything other than a normal boot. + // fastbootd, in particular, needs the real values so it can allow flashing on + // unlocked bootloaders. + if (!isNormalBoot) { + return; + } + + // Spoof properties + InitPropertySet("ro.boot.flash.locked", "1"); + InitPropertySet("ro.boot.verifiedbootstate", "green"); + InitPropertySet("ro.boot.veritymode", "enforcing"); + InitPropertySet("ro.boot.vbmeta.device_state", "locked"); +} + void PropertyInit() { selinux_callback cb; cb.func_audit = PropertyAuditCallback; @@ -1368,6 +1398,9 @@ void PropertyInit() { LOG(FATAL) << "Failed to load serialized property info file"; } + // Report valid verified boot chain to help pass Google SafetyNet integrity checks + SetSafetyNetProps(); + // If arguments are passed both on the command line and in DT, // properties set in DT always have priority over the command-line ones. ProcessKernelDt(); |