diff --git a/fs_mgr/libfs_avb/avb_ops.cpp b/fs_mgr/libfs_avb/avb_ops.cpp index f56a51744..c985a9784 100644 --- a/fs_mgr/libfs_avb/avb_ops.cpp +++ b/fs_mgr/libfs_avb/avb_ops.cpp @@ -170,16 +170,32 @@ AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t of AvbSlotVerifyResult FsManagerAvbOps::AvbSlotVerify(const std::string& ab_suffix, AvbSlotVerifyFlags flags, - AvbSlotVerifyData** out_data) { + std::vector* out_vbmeta_images) { // Invokes avb_slot_verify() to load and verify all vbmeta images. // Sets requested_partitions to nullptr as it's to copy the contents // of HASH partitions into handle>avb_slot_data_, which is not required as // fs_mgr only deals with HASHTREE partitions. const char* requested_partitions[] = {nullptr}; + + // Local resource to store vbmeta images from avb_slot_verify(); + AvbSlotVerifyData* avb_slot_data; + // The |hashtree_error_mode| field doesn't matter as it only // influences the generated kernel cmdline parameters. - return avb_slot_verify(&avb_ops_, requested_partitions, ab_suffix.c_str(), flags, - AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, out_data); + auto verify_result = + avb_slot_verify(&avb_ops_, requested_partitions, ab_suffix.c_str(), flags, + AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &avb_slot_data); + + // Copies avb_slot_data->vbmeta_images[]. + for (size_t i = 0; i < avb_slot_data->num_vbmeta_images; i++) { + out_vbmeta_images->emplace_back(VBMetaData(avb_slot_data->vbmeta_images[i].vbmeta_data, + avb_slot_data->vbmeta_images[i].vbmeta_size)); + } + + // Free the local resource. + avb_slot_verify_data_free(avb_slot_data); + + return verify_result; } } // namespace fs_mgr diff --git a/fs_mgr/libfs_avb/avb_ops.h b/fs_mgr/libfs_avb/avb_ops.h index e6b33c2b9..c0f12aa79 100644 --- a/fs_mgr/libfs_avb/avb_ops.h +++ b/fs_mgr/libfs_avb/avb_ops.h @@ -25,7 +25,9 @@ #pragma once #include +#include +#include #include namespace android { @@ -55,7 +57,7 @@ class FsManagerAvbOps { void* buffer, size_t* out_num_read); AvbSlotVerifyResult AvbSlotVerify(const std::string& ab_suffix, AvbSlotVerifyFlags flags, - AvbSlotVerifyData** out_data); + std::vector* out_vbmeta_images); private: AvbOps avb_ops_; diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp index 89c755ea6..cf920f9c2 100644 --- a/fs_mgr/libfs_avb/fs_avb.cpp +++ b/fs_mgr/libfs_avb/fs_avb.cpp @@ -99,14 +99,13 @@ static std::string bytes_to_hex(const uint8_t* bytes, size_t bytes_len) { } template -static std::pair verify_vbmeta_digest(const AvbSlotVerifyData& verify_data, +static std::pair verify_vbmeta_digest(const std::vector& vbmeta_images, const uint8_t* expected_digest) { size_t total_size = 0; Hasher hasher; - for (size_t n = 0; n < verify_data.num_vbmeta_images; n++) { - hasher.update(verify_data.vbmeta_images[n].vbmeta_data, - verify_data.vbmeta_images[n].vbmeta_size); - total_size += verify_data.vbmeta_images[n].vbmeta_size; + for (size_t n = 0; n < vbmeta_images.size(); n++) { + hasher.update(vbmeta_images[n].vbmeta_data(), vbmeta_images[n].vbmeta_size()); + total_size += vbmeta_images[n].vbmeta_size(); } bool matched = (memcmp(hasher.finalize(), expected_digest, Hasher::DIGEST_SIZE) == 0); @@ -123,7 +122,7 @@ class AvbVerifier { public: // The factory method to return a unique_ptr static std::unique_ptr Create(); - bool VerifyVbmetaImages(const AvbSlotVerifyData& verify_data); + bool VerifyVbmetaImages(const std::vector& vbmeta_images); protected: AvbVerifier() = default; @@ -186,8 +185,8 @@ std::unique_ptr AvbVerifier::Create() { return avb_verifier; } -bool AvbVerifier::VerifyVbmetaImages(const AvbSlotVerifyData& verify_data) { - if (verify_data.num_vbmeta_images == 0) { +bool AvbVerifier::VerifyVbmetaImages(const std::vector& vbmeta_images) { + if (vbmeta_images.empty()) { LERROR << "No vbmeta images"; return false; } @@ -197,10 +196,10 @@ bool AvbVerifier::VerifyVbmetaImages(const AvbSlotVerifyData& verify_data) { if (hash_alg_ == kSHA256) { std::tie(total_size, digest_matched) = - verify_vbmeta_digest(verify_data, digest_); + verify_vbmeta_digest(vbmeta_images, digest_); } else if (hash_alg_ == kSHA512) { std::tie(total_size, digest_matched) = - verify_vbmeta_digest(verify_data, digest_); + verify_vbmeta_digest(vbmeta_images, digest_); } if (total_size != vbmeta_size_) { @@ -306,18 +305,18 @@ static bool hashtree_dm_verity_setup(FstabEntry* fstab_entry, } static bool get_hashtree_descriptor(const std::string& partition_name, - const AvbSlotVerifyData& verify_data, + const std::vector& vbmeta_images, AvbHashtreeDescriptor* out_hashtree_desc, std::string* out_salt, std::string* out_digest) { bool found = false; const uint8_t* desc_partition_name; - for (size_t i = 0; i < verify_data.num_vbmeta_images && !found; i++) { + for (size_t i = 0; i < vbmeta_images.size() && !found; i++) { // Get descriptors from vbmeta_images[i]. size_t num_descriptors; std::unique_ptr descriptors( - avb_descriptor_get_all(verify_data.vbmeta_images[i].vbmeta_data, - verify_data.vbmeta_images[i].vbmeta_size, &num_descriptors), + avb_descriptor_get_all(vbmeta_images[i].vbmeta_data(), + vbmeta_images[i].vbmeta_size(), &num_descriptors), avb_free); if (!descriptors || num_descriptors < 1) { @@ -377,7 +376,7 @@ AvbUniquePtr AvbHandle::Open() { AvbSlotVerifyFlags flags = is_device_unlocked ? 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->avb_slot_data_); + avb_ops.AvbSlotVerify(fs_mgr_get_slot_suffix(), flags, &avb_handle->vbmeta_images_); // Only allow two verify results: // - AVB_SLOT_VERIFY_RESULT_OK. @@ -417,8 +416,7 @@ AvbUniquePtr AvbHandle::Open() { // and AVB HASHTREE descriptor(s). AvbVBMetaImageHeader vbmeta_header; avb_vbmeta_image_header_to_host_byte_order( - (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data, - &vbmeta_header); + (AvbVBMetaImageHeader*)avb_handle->vbmeta_images_[0].vbmeta_data(), &vbmeta_header); bool verification_disabled = ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED); @@ -431,7 +429,7 @@ AvbUniquePtr AvbHandle::Open() { LERROR << "Failed to create AvbVerifier"; return nullptr; } - if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) { + if (!avb_verifier->VerifyVbmetaImages(avb_handle->vbmeta_images_)) { LERROR << "VerifyVbmetaImages failed"; return nullptr; } @@ -449,8 +447,7 @@ AvbUniquePtr AvbHandle::Open() { } AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev) { - if (!fstab_entry || status_ == kAvbHandleUninitialized || !avb_slot_data_ || - avb_slot_data_->num_vbmeta_images < 1) { + if (!fstab_entry || status_ == kAvbHandleUninitialized || vbmeta_images_.size() < 1) { return AvbHashtreeResult::kFail; } @@ -478,7 +475,7 @@ AvbHashtreeResult AvbHandle::SetUpAvbHashtree(FstabEntry* fstab_entry, bool wait AvbHashtreeDescriptor hashtree_descriptor; std::string salt; std::string root_digest; - if (!get_hashtree_descriptor(partition_name, *avb_slot_data_, &hashtree_descriptor, &salt, + if (!get_hashtree_descriptor(partition_name, vbmeta_images_, &hashtree_descriptor, &salt, &root_digest)) { return AvbHashtreeResult::kFail; } diff --git a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h index 08bdbdce2..0c2b2318c 100644 --- a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h +++ b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -31,6 +32,35 @@ enum class AvbHashtreeResult { kDisabled, }; +class VBMetaData { + public: + // Constructors + VBMetaData() : vbmeta_ptr_(nullptr), vbmeta_size_(0){}; + + VBMetaData(uint8_t* data, size_t size) + : vbmeta_ptr_(new (std::nothrow) uint8_t[size]), vbmeta_size_(size) { + // The ownership of data is NOT transferred, i.e., the caller still + // needs to release the memory as we make a copy here. + memcpy(vbmeta_ptr_.get(), data, size * sizeof(uint8_t)); + } + + explicit VBMetaData(size_t size) + : vbmeta_ptr_(new (std::nothrow) uint8_t[size]), vbmeta_size_(size) {} + + // Get methods for each data member. + const std::string& device_path() const { return device_path_; } + uint8_t* vbmeta_data() const { return vbmeta_ptr_.get(); } + const size_t& vbmeta_size() const { return vbmeta_size_; } + + // Maximum size of a vbmeta data - 64 KiB. + static const size_t kMaxVBMetaSize = 64 * 1024; + + private: + std::string device_path_; + std::unique_ptr vbmeta_ptr_; + size_t vbmeta_size_; +}; + class FsManagerAvbOps; class AvbHandle; @@ -43,7 +73,7 @@ class AvbHandle { public: // The factory method to return a AvbUniquePtr that holds // the verified AVB (external/avb) metadata of all verified partitions - // in avb_slot_data_.vbmeta_images[]. + // in vbmeta_images_. // // The metadata is checked against the following values from /proc/cmdline. // - androidboot.vbmeta.{hash_alg, size, digest}. @@ -95,12 +125,6 @@ class AvbHandle { AvbHandle(AvbHandle&&) noexcept = delete; // no move AvbHandle& operator=(AvbHandle&&) noexcept = delete; // no move assignment - ~AvbHandle() { - if (avb_slot_data_) { - avb_slot_verify_data_free(avb_slot_data_); - } - }; - private: enum AvbHandleStatus { kAvbHandleSuccess = 0, @@ -110,9 +134,9 @@ class AvbHandle { kAvbHandleVerificationError, }; - AvbHandle() : avb_slot_data_(nullptr), status_(kAvbHandleUninitialized) {} + AvbHandle() : status_(kAvbHandleUninitialized) {} - AvbSlotVerifyData* avb_slot_data_; + std::vector vbmeta_images_; AvbHandleStatus status_; std::string avb_version_; };