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_;
 };