From 0b2c5cde1f7d380d4aa5f4f249049e6fccd5ba0e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 5 Jul 2023 18:02:09 +0000 Subject: [PATCH 1/2] init: remove unfinished fsverity signature support for APEX sepolicy The APEX sepolicy feature has unfinished support for verifying the sepolicy file using fsverity with a builtin signature. However, this was never finished and doesn't really make sense, since the already-implemented scheme that uses a full-file hash combined with a userspace signature check is better suited to the problem. Therefore, remove this unfinished code. Bug: 290064770 Test: presubmit and booting Cuttlefish Change-Id: I3403a3303bcea32c7340642b843cd1541fe1fd2f --- init/Android.bp | 2 -- init/selinux.cpp | 46 ++-------------------------------------------- 2 files changed, 2 insertions(+), 46 deletions(-) diff --git a/init/Android.bp b/init/Android.bp index 1af398a9a..4416b9dc2 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -166,11 +166,9 @@ libinit_cc_defaults { "libbootloader_message", "libc++fs", "libcgrouprc_format", - "libfsverity_init", "liblmkd_utils", "liblz4", "libzstd", - "libmini_keyctl_static", "libmodprobe", "libprocinfo", "libprotobuf-cpp-lite", diff --git a/init/selinux.cpp b/init/selinux.cpp index e0ef4913c..b6d483a47 100644 --- a/init/selinux.cpp +++ b/init/selinux.cpp @@ -74,10 +74,8 @@ #include #include #include -#include #include #include -#include #include #include @@ -510,7 +508,6 @@ bool OpenMonolithicPolicy(PolicyFile* policy_file) { constexpr const char* kSigningCertRelease = "/system/etc/selinux/com.android.sepolicy.cert-release.der"; -constexpr const char* kFsVerityProcPath = "/proc/sys/fs/verity"; const std::string kSepolicyApexMetadataDir = "/metadata/sepolicy/"; const std::string kSepolicyApexSystemDir = "/system/etc/selinux/apex/"; const std::string kSepolicyZip = "SEPolicy.zip"; @@ -614,24 +611,6 @@ Result GetPolicyFromApex(const std::string& dir) { return {}; } -Result LoadSepolicyApexCerts() { - key_serial_t keyring_id = android::GetKeyringId(".fs-verity"); - if (keyring_id < 0) { - return Error() << "Failed to find .fs-verity keyring id"; - } - - // TODO(b/199914227) the release key should always exist. Once it's checked in, start - // throwing an error here if it doesn't exist. - if (access(kSigningCertRelease, F_OK) == 0) { - LoadKeyFromFile(keyring_id, "fsv_sepolicy_apex_release", kSigningCertRelease); - } - return {}; -} - -Result SepolicyFsVerityCheck() { - return Error() << "TODO implement support for fsverity SEPolicy."; -} - Result SepolicyCheckSignature(const std::string& dir) { std::string signature; if (!android::base::ReadFileToString(dir + kSepolicySignature, &signature)) { @@ -654,18 +633,7 @@ Result SepolicyCheckSignature(const std::string& dir) { return verifySignature(sepolicyStr, signature, *releaseKey); } -Result SepolicyVerify(const std::string& dir, bool supportsFsVerity) { - if (supportsFsVerity) { - auto fsVerityCheck = SepolicyFsVerityCheck(); - if (fsVerityCheck.ok()) { - return fsVerityCheck; - } - // TODO(b/199914227) If the device supports fsverity, but we fail here, we should fail to - // boot and not carry on. For now, fallback to a signature checkuntil the fsverity - // logic is implemented. - LOG(INFO) << "Falling back to standard signature check. " << fsVerityCheck.error(); - } - +Result SepolicyVerify(const std::string& dir) { auto sepolicySignature = SepolicyCheckSignature(dir); if (!sepolicySignature.ok()) { return Error() << "Apex SEPolicy failed signature check"; @@ -698,23 +666,13 @@ void CleanupApexSepolicy() { // 6. Sets selinux into enforcing mode and continues normal booting. // void PrepareApexSepolicy() { - bool supportsFsVerity = access(kFsVerityProcPath, F_OK) == 0; - if (supportsFsVerity) { - auto loadSepolicyApexCerts = LoadSepolicyApexCerts(); - if (!loadSepolicyApexCerts.ok()) { - // TODO(b/199914227) If the device supports fsverity, but we fail here, we should fail - // to boot and not carry on. For now, fallback to a signature checkuntil the fsverity - // logic is implemented. - LOG(INFO) << loadSepolicyApexCerts.error(); - } - } // If apex sepolicy zip exists in /metadata/sepolicy, use that, otherwise use version on // /system. auto dir = (access((kSepolicyApexMetadataDir + kSepolicyZip).c_str(), F_OK) == 0) ? kSepolicyApexMetadataDir : kSepolicyApexSystemDir; - auto sepolicyVerify = SepolicyVerify(dir, supportsFsVerity); + auto sepolicyVerify = SepolicyVerify(dir); if (!sepolicyVerify.ok()) { LOG(INFO) << "Error: " << sepolicyVerify.error(); // If signature verification fails, fall back to version on /system. From 79a67391bde590704c199a8567661ad130c4d90e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 6 Jul 2023 17:27:46 +0000 Subject: [PATCH 2/2] init.rc: stop using fsverity_init --lock Remove the code that "locked" the .fs-verity keyring at a certain point in the boot. It probably was thought that this achieved some useful security property, which is a bit questionable. Regardless, Android no longer uses fsverity builtin signatures. The only code that is still being kept around is enough to access existing files on old kernels, and for this "locking" the keyring is definitely not essential. Bug: 290064770 Test: presubmit and booting Cuttlefish Change-Id: Ide5729aeac5772658b2a3f0abe835988b8842b02 --- rootdir/init.rc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rootdir/init.rc b/rootdir/init.rc index a8b78d5d8..3d45df249 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -1021,13 +1021,9 @@ on post-fs-data # Must start after 'derive_classpath' to have *CLASSPATH variables set. start odsign - # Before we can lock keys and proceed to the next boot stage, wait for - # odsign to be done with the key + # Wait for odsign to be done with the key. wait_for_prop odsign.key.done 1 - # Lock the fs-verity keyring, so no more keys can be added - exec -- /system/bin/fsverity_init --lock - # Bump the boot level to 1000000000; this prevents further on-device signing. # This is a special value that shuts down the thread which listens for # further updates.