Preserving /avb/* keys to /metadata
Those keys will be used for key revocation check by DSU installation
service. Note that failing to copy those keys to /metadata is NOT fatal,
because it is auxiliary to perform public key matching prior to booting
into DSU images on next boot. The actual key matching will still be done
on next DSU boot.
Bug: 146910547
Test: boot device, checks the avb keys are copied to /metadata/gsi/dsu/avb/.
Change-Id: I25a4eba82e84288bac7a859205c920628a063651
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 21663e6..622e457 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -21,6 +21,7 @@
#include <unistd.h>
#include <chrono>
+#include <filesystem>
#include <map>
#include <memory>
#include <set>
@@ -99,7 +100,11 @@
void GetDmLinearMetadataDevice(std::set<std::string>* devices);
bool InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata);
void UseDsuIfPresent();
+ // Reads all fstab.avb_keys from the ramdisk for first-stage mount.
void PreloadAvbKeys();
+ // Copies /avb/*.avbpubkey used for DSU from the ramdisk to /metadata for key
+ // revocation check by DSU installation service.
+ void CopyDsuAvbKeys();
ListenerAction UeventCallback(const Uevent& uevent, std::set<std::string>* required_devices);
@@ -595,7 +600,12 @@
return entry.mount_point == "/metadata";
});
if (metadata_partition != fstab_.end()) {
- MountPartition(metadata_partition, true /* erase_same_mounts */);
+ if (MountPartition(metadata_partition, true /* erase_same_mounts */)) {
+ // Copies DSU AVB keys from the ramdisk to /metadata.
+ // Must be done before the following TrySwitchSystemAsRoot().
+ // Otherwise, ramdisk will be inaccessible after switching root.
+ CopyDsuAvbKeys();
+ }
}
if (!CreateLogicalPartitions()) return false;
@@ -663,6 +673,27 @@
return true;
}
+// Preserves /avb/*.avbpubkey to /metadata/gsi/dsu/avb/, so they can be used for
+// key revocation check by DSU installation service. Note that failing to
+// copy files to /metadata is NOT fatal, because it is auxiliary to perform
+// public key matching before booting into DSU images on next boot. The actual
+// public key matching will still be done on next boot to DSU.
+void FirstStageMount::CopyDsuAvbKeys() {
+ std::error_code ec;
+ // Removing existing keys in gsi::kDsuAvbKeyDir as they might be stale.
+ std::filesystem::remove_all(gsi::kDsuAvbKeyDir, ec);
+ if (ec) {
+ LOG(ERROR) << "Failed to remove directory " << gsi::kDsuAvbKeyDir << ": " << ec.message();
+ }
+ // Copy keys from the ramdisk /avb/* to gsi::kDsuAvbKeyDir.
+ static constexpr char kRamdiskAvbKeyDir[] = "/avb";
+ std::filesystem::copy(kRamdiskAvbKeyDir, gsi::kDsuAvbKeyDir, ec);
+ if (ec) {
+ LOG(ERROR) << "Failed to copy " << kRamdiskAvbKeyDir << " into " << gsi::kDsuAvbKeyDir
+ << ": " << ec.message();
+ }
+}
+
void FirstStageMount::UseDsuIfPresent() {
std::string error;
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 41007c1..c5b7576 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -65,6 +65,7 @@
#include <android-base/parseint.h>
#include <android-base/unique_fd.h>
#include <fs_avb/fs_avb.h>
+#include <libgsi/libgsi.h>
#include <selinux/android.h>
#include "debug_ramdisk.h"
@@ -533,6 +534,8 @@
selinux_android_restorecon("/apex", 0);
selinux_android_restorecon("/linkerconfig", 0);
+
+ selinux_android_restorecon(gsi::kDsuAvbKeyDir, SELINUX_ANDROID_RESTORECON_RECURSE);
}
int SelinuxKlogCallback(int type, const char* fmt, ...) {