From 4859e0ca0f7fc5da217e8b388da76ece41dd726e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 24 Jun 2021 11:13:24 -0700 Subject: [PATCH] Ignore too-early earlyBootEnded on FDE devices Don't call IKeystoreMaintenance::earlyBootEnded() too early on FDE devices, so that keystore2 doesn't have to be restarted. Bug: 192090857 Test: Tested FDE on Cuttlefish, both first and non-first boots. Verified via log that earlyBootEnded is now called only when it should be, and that keystore2 no longer has to be restarted. Change-Id: I03f816db194a8276ad19ca99b3c8894e8a5fed23 --- VoldNativeService.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 5ea72bb..706a1c3 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -938,10 +939,42 @@ static void initializeIncFs() { incfs::features(); } +// This is missing from the kernel UAPI headers. +#define ST_RDONLY 0x0001 + +// FDE devices run the post-fs-data trigger (and hence also earlyBootEnded) +// multiple times, sometimes prior to the real /data being mounted. That causes +// keystore2 to try to open a file in /data, causing it to panic or have to be +// killed by vold later, causing problems (vold failing to connect to keystore2, +// or keystore2 operations erroring out later). As a workaround to keep FDE +// working, ignore these too-early calls to earlyBootEnded. +// +// This can be removed when support for FDE is removed. +static bool IgnoreEarlyBootEnded() { + // The statfs("/data") below should be sufficient by itself, but to be safe + // we also explicitly return false on FBE devices. (This really should be + // ro.crypto.type != "block" for "non-FDE devices", but on FDE devices this + // is sometimes called before ro.crypto.type gets set.) + if (fscrypt_is_native()) return false; + + struct statfs buf; + if (statfs(DATA_MNT_POINT, &buf) != 0) { + PLOG(ERROR) << "statfs(\"/data\") failed"; + return false; + } + if (buf.f_type == TMPFS_MAGIC || (buf.f_flags & ST_RDONLY)) { + LOG(INFO) << "Ignoring earlyBootEnded since real /data isn't mounted yet"; + return true; + } + return false; +} + binder::Status VoldNativeService::earlyBootEnded() { ENFORCE_SYSTEM_OR_ROOT; ACQUIRE_LOCK; + if (IgnoreEarlyBootEnded()) return Ok(); + initializeIncFs(); Keymaster::earlyBootEnded(); return Ok();