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
This commit is contained in:
Bowgo Tsai 2020-01-20 18:03:58 +08:00
parent ab19b995be
commit 196cc58781
2 changed files with 35 additions and 1 deletions

View file

@ -21,6 +21,7 @@
#include <unistd.h>
#include <chrono>
#include <filesystem>
#include <map>
#include <memory>
#include <set>
@ -99,7 +100,11 @@ class FirstStageMount {
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 @@ bool FirstStageMount::MountPartitions() {
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 @@ bool FirstStageMount::MountPartitions() {
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;

View file

@ -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 @@ void SelinuxRestoreContext() {
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, ...) {