summaryrefslogtreecommitdiff
path: root/init/property_service.cpp
diff options
context:
space:
mode:
authorDanny Lin <danny@kdrag0n.dev>2020-10-07 00:24:54 -0700
committeralk3pInjection <webmaster@raspii.tech>2022-01-26 23:10:42 +0800
commitadbb1c10dd503804988344c1905df3c23973cf0d (patch)
treed328d4a1d2c9395ca91a55e6103df8a22991398b /init/property_service.cpp
parent375d7503efe8553bf21384d48be54d6e946f8514 (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
Diffstat (limited to 'init/property_service.cpp')
-rw-r--r--init/property_service.cpp33
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();