Merge "fs_mgr_avb: introducing class VBMetaData"
am: aed2ee9664
Change-Id: Ifabb004afbfe16d859328a715777f133bda5ead1
diff --git a/fs_mgr/libfs_avb/avb_ops.cpp b/fs_mgr/libfs_avb/avb_ops.cpp
index f56a517..c985a97 100644
--- a/fs_mgr/libfs_avb/avb_ops.cpp
+++ b/fs_mgr/libfs_avb/avb_ops.cpp
@@ -170,16 +170,32 @@
AvbSlotVerifyResult FsManagerAvbOps::AvbSlotVerify(const std::string& ab_suffix,
AvbSlotVerifyFlags flags,
- AvbSlotVerifyData** out_data) {
+ std::vector<VBMetaData>* 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 e6b33c2..c0f12aa 100644
--- a/fs_mgr/libfs_avb/avb_ops.h
+++ b/fs_mgr/libfs_avb/avb_ops.h
@@ -25,7 +25,9 @@
#pragma once
#include <string>
+#include <vector>
+#include <fs_avb/fs_avb.h>
#include <libavb/libavb.h>
namespace android {
@@ -55,7 +57,7 @@
void* buffer, size_t* out_num_read);
AvbSlotVerifyResult AvbSlotVerify(const std::string& ab_suffix, AvbSlotVerifyFlags flags,
- AvbSlotVerifyData** out_data);
+ std::vector<VBMetaData>* 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 89c755e..cf920f9 100644
--- a/fs_mgr/libfs_avb/fs_avb.cpp
+++ b/fs_mgr/libfs_avb/fs_avb.cpp
@@ -99,14 +99,13 @@
}
template <typename Hasher>
-static std::pair<size_t, bool> verify_vbmeta_digest(const AvbSlotVerifyData& verify_data,
+static std::pair<size_t, bool> verify_vbmeta_digest(const std::vector<VBMetaData>& 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 @@
public:
// The factory method to return a unique_ptr<AvbVerifier>
static std::unique_ptr<AvbVerifier> Create();
- bool VerifyVbmetaImages(const AvbSlotVerifyData& verify_data);
+ bool VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_images);
protected:
AvbVerifier() = default;
@@ -186,8 +185,8 @@
return avb_verifier;
}
-bool AvbVerifier::VerifyVbmetaImages(const AvbSlotVerifyData& verify_data) {
- if (verify_data.num_vbmeta_images == 0) {
+bool AvbVerifier::VerifyVbmetaImages(const std::vector<VBMetaData>& vbmeta_images) {
+ if (vbmeta_images.empty()) {
LERROR << "No vbmeta images";
return false;
}
@@ -197,10 +196,10 @@
if (hash_alg_ == kSHA256) {
std::tie(total_size, digest_matched) =
- verify_vbmeta_digest<SHA256Hasher>(verify_data, digest_);
+ verify_vbmeta_digest<SHA256Hasher>(vbmeta_images, digest_);
} else if (hash_alg_ == kSHA512) {
std::tie(total_size, digest_matched) =
- verify_vbmeta_digest<SHA512Hasher>(verify_data, digest_);
+ verify_vbmeta_digest<SHA512Hasher>(vbmeta_images, digest_);
}
if (total_size != vbmeta_size_) {
@@ -306,18 +305,18 @@
}
static bool get_hashtree_descriptor(const std::string& partition_name,
- const AvbSlotVerifyData& verify_data,
+ const std::vector<VBMetaData>& 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<const AvbDescriptor* [], decltype(&avb_free)> 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 @@
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 @@
// 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 @@
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 @@
}
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 @@
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 08bdbdc..0c2b231 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 <memory>
#include <string>
+#include <vector>
#include <fstab/fstab.h>
#include <libavb/libavb.h>
@@ -31,6 +32,35 @@
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<uint8_t[]> vbmeta_ptr_;
+ size_t vbmeta_size_;
+};
+
class FsManagerAvbOps;
class AvbHandle;
@@ -43,7 +73,7 @@
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 @@
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 @@
kAvbHandleVerificationError,
};
- AvbHandle() : avb_slot_data_(nullptr), status_(kAvbHandleUninitialized) {}
+ AvbHandle() : status_(kAvbHandleUninitialized) {}
- AvbSlotVerifyData* avb_slot_data_;
+ std::vector<VBMetaData> vbmeta_images_;
AvbHandleStatus status_;
std::string avb_version_;
};