libfs_avb: Allow overriding the slot suffix.
There is no easy way to override fs_mgr_get_slot_suffix for testing or for simulating slot switches. It relies on global properties, and since fstab is usually a static library, linked multiple times, we can't just stick a global variable in fs_mgr_slotselect. libfs_avb already takes slot suffix arguments in various places. This CL extends that by adding arguments to AvbHandle and FsManagerAvbOps. Bug: N/A Test: snapshotctl Change-Id: Ide7f052b38249d6bc79a6a2c124baf8ca08bcc3b
This commit is contained in:
parent
1cf0e90409
commit
0ff0eeed77
6 changed files with 48 additions and 14 deletions
|
@ -108,8 +108,8 @@ static AvbIOResult get_size_of_partition(AvbOps* ops ATTRIBUTE_UNUSED,
|
|||
// Converts a partition name (with ab_suffix) to the corresponding mount point.
|
||||
// e.g., "system_a" => "/system",
|
||||
// e.g., "vendor_a" => "/vendor",
|
||||
static std::string DeriveMountPoint(const std::string& partition_name) {
|
||||
const std::string ab_suffix = fs_mgr_get_slot_suffix();
|
||||
static std::string DeriveMountPoint(const std::string& partition_name,
|
||||
const std::string& ab_suffix) {
|
||||
std::string mount_point(partition_name);
|
||||
auto found = partition_name.rfind(ab_suffix);
|
||||
if (found != std::string::npos) {
|
||||
|
@ -119,7 +119,7 @@ static std::string DeriveMountPoint(const std::string& partition_name) {
|
|||
return "/" + mount_point;
|
||||
}
|
||||
|
||||
FsManagerAvbOps::FsManagerAvbOps() {
|
||||
FsManagerAvbOps::FsManagerAvbOps(const std::string& slot_suffix) {
|
||||
// We only need to provide the implementation of read_from_partition()
|
||||
// operation since that's all what is being used by the avb_slot_verify().
|
||||
// Other I/O operations are only required in bootloader but not in
|
||||
|
@ -135,6 +135,11 @@ FsManagerAvbOps::FsManagerAvbOps() {
|
|||
|
||||
// Sets user_data for GetInstanceFromAvbOps() to convert it back to FsManagerAvbOps.
|
||||
avb_ops_.user_data = this;
|
||||
|
||||
slot_suffix_ = slot_suffix;
|
||||
if (slot_suffix_.empty()) {
|
||||
slot_suffix_ = fs_mgr_get_slot_suffix();
|
||||
}
|
||||
}
|
||||
|
||||
// Given a partition name (with ab_suffix), e.g., system_a, returns the corresponding
|
||||
|
@ -149,7 +154,7 @@ std::string FsManagerAvbOps::GetLogicalPath(const std::string& partition_name) {
|
|||
return "";
|
||||
}
|
||||
|
||||
const auto mount_point = DeriveMountPoint(partition_name);
|
||||
const auto mount_point = DeriveMountPoint(partition_name, slot_suffix_);
|
||||
if (mount_point.empty()) return "";
|
||||
|
||||
auto fstab_entry = GetEntryForMountPoint(&fstab_, mount_point);
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace fs_mgr {
|
|||
//
|
||||
class FsManagerAvbOps {
|
||||
public:
|
||||
FsManagerAvbOps();
|
||||
explicit FsManagerAvbOps(const std::string& slot_suffix = {});
|
||||
|
||||
static FsManagerAvbOps* GetInstanceFromAvbOps(AvbOps* ops) {
|
||||
return reinterpret_cast<FsManagerAvbOps*>(ops->user_data);
|
||||
|
@ -66,6 +66,7 @@ class FsManagerAvbOps {
|
|||
std::string GetPartitionPath(const char* partition_name);
|
||||
AvbOps avb_ops_;
|
||||
Fstab fstab_;
|
||||
std::string slot_suffix_;
|
||||
};
|
||||
|
||||
} // namespace fs_mgr
|
||||
|
|
|
@ -182,6 +182,11 @@ bool AvbVerifier::VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_image
|
|||
|
||||
// class AvbHandle
|
||||
// ---------------
|
||||
AvbHandle::AvbHandle() : status_(AvbHandleStatus::kUninitialized) {
|
||||
slot_suffix_ = fs_mgr_get_slot_suffix();
|
||||
other_slot_suffix_ = fs_mgr_get_other_slot_suffix();
|
||||
}
|
||||
|
||||
AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(
|
||||
const std::string& partition_name, const std::string& ab_suffix,
|
||||
const std::string& ab_other_suffix, const std::string& expected_public_key_path,
|
||||
|
@ -194,6 +199,9 @@ AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
avb_handle->slot_suffix_ = ab_suffix;
|
||||
avb_handle->other_slot_suffix_ = ab_other_suffix;
|
||||
|
||||
std::string expected_key_blob;
|
||||
if (!expected_public_key_path.empty()) {
|
||||
if (access(expected_public_key_path.c_str(), F_OK) != 0) {
|
||||
|
@ -373,9 +381,14 @@ AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(const FstabEntry& fstab_entry,
|
|||
return avb_handle;
|
||||
}
|
||||
|
||||
AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta() {
|
||||
AvbUniquePtr AvbHandle::LoadAndVerifyVbmeta(const std::string& slot_suffix) {
|
||||
// Loads inline vbmeta images, starting from /vbmeta.
|
||||
return LoadAndVerifyVbmeta("vbmeta", fs_mgr_get_slot_suffix(), fs_mgr_get_other_slot_suffix(),
|
||||
auto suffix = slot_suffix;
|
||||
if (suffix.empty()) {
|
||||
suffix = fs_mgr_get_slot_suffix();
|
||||
}
|
||||
auto other_suffix = android::fs_mgr::OtherSlotSuffix(suffix);
|
||||
return LoadAndVerifyVbmeta("vbmeta", suffix, other_suffix,
|
||||
{} /* expected_public_key, already checked by bootloader */,
|
||||
HashAlgorithm::kSHA256,
|
||||
IsAvbPermissive(), /* allow_verification_error */
|
||||
|
@ -399,7 +412,7 @@ AvbUniquePtr AvbHandle::Open() {
|
|||
? AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
|
||||
: AVB_SLOT_VERIFY_FLAGS_NONE;
|
||||
AvbSlotVerifyResult verify_result =
|
||||
avb_ops.AvbSlotVerify(fs_mgr_get_slot_suffix(), flags, &avb_handle->vbmeta_images_);
|
||||
avb_ops.AvbSlotVerify(avb_handle->slot_suffix_, flags, &avb_handle->vbmeta_images_);
|
||||
|
||||
// Only allow the following verify results:
|
||||
// - AVB_SLOT_VERIFY_RESULT_OK.
|
||||
|
@ -492,7 +505,7 @@ AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait
|
|||
}
|
||||
|
||||
if (!LoadAvbHashtreeToEnableVerity(fstab_entry, wait_for_verity_dev, vbmeta_images_,
|
||||
fs_mgr_get_slot_suffix(), fs_mgr_get_other_slot_suffix())) {
|
||||
slot_suffix_, other_slot_suffix_)) {
|
||||
return AvbHashtreeResult::kFail;
|
||||
}
|
||||
|
||||
|
@ -526,8 +539,8 @@ std::string AvbHandle::GetSecurityPatchLevel(const FstabEntry& fstab_entry) cons
|
|||
if (vbmeta_images_.size() < 1) {
|
||||
return "";
|
||||
}
|
||||
std::string avb_partition_name = DeriveAvbPartitionName(fstab_entry, fs_mgr_get_slot_suffix(),
|
||||
fs_mgr_get_other_slot_suffix());
|
||||
std::string avb_partition_name =
|
||||
DeriveAvbPartitionName(fstab_entry, slot_suffix_, other_slot_suffix_);
|
||||
auto avb_prop_name = "com.android.build." + avb_partition_name + ".security_patch";
|
||||
return GetAvbPropertyDescriptor(avb_prop_name, vbmeta_images_);
|
||||
}
|
||||
|
|
|
@ -83,8 +83,8 @@ class AvbHandle {
|
|||
// is verified and can be trusted.
|
||||
//
|
||||
// TODO(bowgotsai): remove Open() and switch to LoadAndVerifyVbmeta().
|
||||
static AvbUniquePtr Open(); // loads inline vbmeta, via libavb.
|
||||
static AvbUniquePtr LoadAndVerifyVbmeta(); // loads inline vbmeta.
|
||||
static AvbUniquePtr Open(); // loads inline vbmeta, via libavb.
|
||||
static AvbUniquePtr LoadAndVerifyVbmeta(const std::string& slot_suffix = {});
|
||||
|
||||
// The caller can specify optional preload_avb_key_blobs for public key matching.
|
||||
// This is mostly for init to preload AVB keys before chroot into /system.
|
||||
|
@ -137,12 +137,14 @@ class AvbHandle {
|
|||
AvbHandle& operator=(AvbHandle&&) noexcept = delete; // no move assignment
|
||||
|
||||
private:
|
||||
AvbHandle() : status_(AvbHandleStatus::kUninitialized) {}
|
||||
AvbHandle();
|
||||
|
||||
std::vector<VBMetaData> vbmeta_images_;
|
||||
VBMetaInfo vbmeta_info_; // A summary info for vbmeta_images_.
|
||||
AvbHandleStatus status_;
|
||||
std::string avb_version_;
|
||||
std::string slot_suffix_;
|
||||
std::string other_slot_suffix_;
|
||||
};
|
||||
|
||||
} // namespace fs_mgr
|
||||
|
|
|
@ -145,5 +145,8 @@ void ImportKernelCmdline(const std::function<void(std::string, std::string)>& fn
|
|||
// Otherwise returns false and |*out| is not modified.
|
||||
bool GetKernelCmdline(const std::string& key, std::string* out);
|
||||
|
||||
// Return the "other" slot for the given slot suffix.
|
||||
std::string OtherSlotSuffix(const std::string& suffix);
|
||||
|
||||
} // namespace fs_mgr
|
||||
} // namespace android
|
||||
|
|
|
@ -74,3 +74,13 @@ bool fs_mgr_update_for_slotselect(Fstab* fstab) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace android {
|
||||
namespace fs_mgr {
|
||||
|
||||
std::string OtherSlotSuffix(const std::string& suffix) {
|
||||
return other_suffix(suffix);
|
||||
}
|
||||
|
||||
} // namespace fs_mgr
|
||||
} // namespace android
|
||||
|
|
Loading…
Reference in a new issue