Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6db40c7 authored by Bowgo Tsai's avatar Bowgo Tsai Committed by android-build-merger
Browse files

Merge "fs_mgr_avb: refactors how vbmeta is loaded"

am: fc500ddb

Change-Id: Ia964c5180682a5b3929b11f801d943024e8db2f7
parents 4c96971c fc500ddb
Loading
Loading
Loading
Loading
+37 −39
Original line number Diff line number Diff line
@@ -707,6 +707,23 @@ static int handle_encryptable(const struct fstab_rec* rec)
    }
}

static std::string extract_by_name_prefix(struct fstab* fstab) {
    // We assume that there's an entry for the /misc mount point in the
    // fstab file and use that to get the device file by-name prefix.
    // The device needs not to have an actual /misc partition.
    // e.g.,
    //    - /dev/block/platform/soc.0/7824900.sdhci/by-name/misc ->
    //    - /dev/block/platform/soc.0/7824900.sdhci/by-name/
    struct fstab_rec* fstab_entry = fs_mgr_get_entry_for_mount_point(fstab, "/misc");
    if (fstab_entry == nullptr) {
        LERROR << "/misc mount point not found in fstab";
        return "";
    }
    std::string full_path(fstab_entry->blk_device);
    size_t end_slash = full_path.find_last_of("/");
    return full_path.substr(0, end_slash + 1);
}

// TODO: add ueventd notifiers if they don't exist.
// This is just doing a wait_for_device for maximum of 1s
int fs_mgr_test_access(const char *device) {
@@ -750,17 +767,12 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
    int mret = -1;
    int mount_errno = 0;
    int attempted_idx = -1;
    int avb_ret = FS_MGR_SETUP_AVB_FAIL;
    FsManagerAvbUniquePtr avb_handle(nullptr);

    if (!fstab) {
        return -1;
    }

    if (fs_mgr_is_avb_used() &&
        (avb_ret = fs_mgr_load_vbmeta_images(fstab)) == FS_MGR_SETUP_AVB_FAIL) {
        return -1;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        /* Don't mount entries that are managed by vold or not for the mount mode*/
        if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
@@ -799,16 +811,15 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
            wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
        }

        if (fs_mgr_is_avb_used() && (fstab->recs[i].fs_mgr_flags & MF_AVB)) {
            /* If HASHTREE_DISABLED is set (cf. 'adb disable-verity'), we
             * should set up the device without using dm-verity.
             * The actual mounting still take place in the following
             * mount_with_alternatives().
             */
            if (avb_ret == FS_MGR_SETUP_AVB_HASHTREE_DISABLED) {
                LINFO << "AVB HASHTREE disabled";
            } else if (fs_mgr_setup_avb(&fstab->recs[i]) !=
                       FS_MGR_SETUP_AVB_SUCCESS) {
        if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
            if (!avb_handle) {
                avb_handle = FsManagerAvbHandle::Open(extract_by_name_prefix(fstab));
                if (!avb_handle) {
                    LERROR << "Failed to open FsManagerAvbHandle";
                    return -1;
                }
            }
            if (!avb_handle->SetUpAvb(&fstab->recs[i])) {
                LERROR << "Failed to set up AVB on partition: "
                       << fstab->recs[i].mount_point << ", skipping!";
                /* Skips mounting the device. */
@@ -934,10 +945,6 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
        }
    }

    if (fs_mgr_is_avb_used()) {
        fs_mgr_unload_vbmeta_images();
    }

    if (error_count) {
        return -1;
    } else {
@@ -976,17 +983,12 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
    int mount_errors = 0;
    int first_mount_errno = 0;
    char *m;
    int avb_ret = FS_MGR_SETUP_AVB_FAIL;
    FsManagerAvbUniquePtr avb_handle(nullptr);

    if (!fstab) {
        return ret;
    }

    if (fs_mgr_is_avb_used() &&
        (avb_ret = fs_mgr_load_vbmeta_images(fstab)) == FS_MGR_SETUP_AVB_FAIL) {
        return ret;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        if (!fs_match(fstab->recs[i].mount_point, n_name)) {
            continue;
@@ -1021,16 +1023,15 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
            do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i], &fs_stat);
        }

        if (fs_mgr_is_avb_used() && (fstab->recs[i].fs_mgr_flags & MF_AVB)) {
            /* If HASHTREE_DISABLED is set (cf. 'adb disable-verity'), we
             * should set up the device without using dm-verity.
             * The actual mounting still take place in the following
             * mount_with_alternatives().
             */
            if (avb_ret == FS_MGR_SETUP_AVB_HASHTREE_DISABLED) {
                LINFO << "AVB HASHTREE disabled";
            } else if (fs_mgr_setup_avb(&fstab->recs[i]) !=
                       FS_MGR_SETUP_AVB_SUCCESS) {
        if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
            if (!avb_handle) {
                avb_handle = FsManagerAvbHandle::Open(extract_by_name_prefix(fstab));
                if (!avb_handle) {
                    LERROR << "Failed to open FsManagerAvbHandle";
                    return -1;
                }
            }
            if (!avb_handle->SetUpAvb(&fstab->recs[i])) {
                LERROR << "Failed to set up AVB on partition: "
                       << fstab->recs[i].mount_point << ", skipping!";
                /* Skips mounting the device. */
@@ -1079,9 +1080,6 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
    }

out:
    if (fs_mgr_is_avb_used()) {
        fs_mgr_unload_vbmeta_images();
    }
    return ret;
}

+118 −140
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <android-base/file.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <cutils/properties.h>
@@ -85,24 +86,6 @@
        hashtree_desc.fec_offset / hashtree_desc.data_block_size, /* fec_start */  \
        VERITY_TABLE_OPT_IGNZERO, VERITY_TABLE_OPT_RESTART

AvbSlotVerifyData* fs_mgr_avb_verify_data = nullptr;
AvbOps* fs_mgr_avb_ops = nullptr;

enum HashAlgorithm {
    kInvalid = 0,
    kSHA256 = 1,
    kSHA512 = 2,
};

struct androidboot_vbmeta {
    HashAlgorithm hash_alg;
    uint8_t digest[SHA512_DIGEST_LENGTH];
    size_t vbmeta_size;
    bool allow_verification_error;
};

androidboot_vbmeta fs_mgr_vbmeta_prop;

static inline bool nibble_value(const char& c, uint8_t* value) {
    FS_MGR_CHECK(value != nullptr);

@@ -159,27 +142,78 @@ static std::string bytes_to_hex(const uint8_t* bytes, size_t bytes_len) {
    return hex;
}

static bool load_vbmeta_prop(androidboot_vbmeta* vbmeta_prop) {
    FS_MGR_CHECK(vbmeta_prop != nullptr);
template <typename Hasher>
static std::pair<size_t, bool> verify_vbmeta_digest(const AvbSlotVerifyData& verify_data,
                                                    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;
    }

    bool matched = (memcmp(hasher.finalize(), expected_digest, Hasher::DIGEST_SIZE) == 0);

    return std::make_pair(total_size, matched);
}

// Reads the following values from kernel cmdline and provides the
// VerifyVbmetaImages() to verify AvbSlotVerifyData.
//   - androidboot.vbmeta.device_state
//   - androidboot.vbmeta.hash_alg
//   - androidboot.vbmeta.size
//   - androidboot.vbmeta.digest
class FsManagerAvbVerifier {
  public:
    // The factory method to return a unique_ptr<FsManagerAvbVerifier>
    static std::unique_ptr<FsManagerAvbVerifier> Create();
    bool VerifyVbmetaImages(const AvbSlotVerifyData& verify_data);
    bool IsDeviceUnlocked() { return is_device_unlocked_; }

  protected:
    FsManagerAvbVerifier() = default;

  private:
    enum HashAlgorithm {
        kInvalid = 0,
        kSHA256 = 1,
        kSHA512 = 2,
    };

    HashAlgorithm hash_alg_;
    uint8_t digest_[SHA512_DIGEST_LENGTH];
    size_t vbmeta_size_;
    bool is_device_unlocked_;
};

std::unique_ptr<FsManagerAvbVerifier> FsManagerAvbVerifier::Create() {
    std::string cmdline;
    android::base::ReadFileToString("/proc/cmdline", &cmdline);
    if (!android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
        LERROR << "Failed to read /proc/cmdline";
        return nullptr;
    }

    std::string hash_alg;
    std::string digest;
    std::unique_ptr<FsManagerAvbVerifier> avb_verifier(new FsManagerAvbVerifier());
    if (!avb_verifier) {
        LERROR << "Failed to create unique_ptr<FsManagerAvbVerifier>";
        return nullptr;
    }

    std::string digest;
    std::string hash_alg;
    for (const auto& entry : android::base::Split(android::base::Trim(cmdline), " ")) {
        std::vector<std::string> pieces = android::base::Split(entry, "=");
        const std::string& key = pieces[0];
        const std::string& value = pieces[1];

        if (key == "androidboot.vbmeta.device_state") {
            vbmeta_prop->allow_verification_error = (value == "unlocked");
            avb_verifier->is_device_unlocked_ = (value == "unlocked");
        } else if (key == "androidboot.vbmeta.hash_alg") {
            hash_alg = value;
        } else if (key == "androidboot.vbmeta.size") {
            if (!android::base::ParseUint(value.c_str(), &vbmeta_prop->vbmeta_size)) {
                return false;
            if (!android::base::ParseUint(value.c_str(), &avb_verifier->vbmeta_size_)) {
                return nullptr;
            }
        } else if (key == "androidboot.vbmeta.digest") {
            digest = value;
@@ -190,48 +224,31 @@ static bool load_vbmeta_prop(androidboot_vbmeta* vbmeta_prop) {
    size_t expected_digest_size = 0;
    if (hash_alg == "sha256") {
        expected_digest_size = SHA256_DIGEST_LENGTH * 2;
        vbmeta_prop->hash_alg = kSHA256;
        avb_verifier->hash_alg_ = kSHA256;
    } else if (hash_alg == "sha512") {
        expected_digest_size = SHA512_DIGEST_LENGTH * 2;
        vbmeta_prop->hash_alg = kSHA512;
        avb_verifier->hash_alg_ = kSHA512;
    } else {
        LERROR << "Unknown hash algorithm: " << hash_alg.c_str();
        return false;
        return nullptr;
    }

    // Reads digest.
    if (digest.size() != expected_digest_size) {
        LERROR << "Unexpected digest size: " << digest.size()
               << " (expected: " << expected_digest_size << ")";
        return false;
        return nullptr;
    }

    if (!hex_to_bytes(vbmeta_prop->digest, sizeof(vbmeta_prop->digest), digest)) {
    if (!hex_to_bytes(avb_verifier->digest_, sizeof(avb_verifier->digest_), digest)) {
        LERROR << "Hash digest contains non-hexidecimal character: " << digest.c_str();
        return false;
    }

    return true;
}

template <typename Hasher>
static std::pair<size_t, bool> verify_vbmeta_digest(const AvbSlotVerifyData& verify_data,
                                                    const androidboot_vbmeta& vbmeta_prop) {
    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;
        return nullptr;
    }

    bool matched = (memcmp(hasher.finalize(), vbmeta_prop.digest, Hasher::DIGEST_SIZE) == 0);

    return std::make_pair(total_size, matched);
    return avb_verifier;
}

static bool verify_vbmeta_images(const AvbSlotVerifyData& verify_data,
                                 const androidboot_vbmeta& vbmeta_prop) {
bool FsManagerAvbVerifier::VerifyVbmetaImages(const AvbSlotVerifyData& verify_data) {
    if (verify_data.num_vbmeta_images == 0) {
        LERROR << "No vbmeta images";
        return false;
@@ -240,17 +257,17 @@ static bool verify_vbmeta_images(const AvbSlotVerifyData& verify_data,
    size_t total_size = 0;
    bool digest_matched = false;

    if (vbmeta_prop.hash_alg == kSHA256) {
    if (hash_alg_ == kSHA256) {
        std::tie(total_size, digest_matched) =
            verify_vbmeta_digest<SHA256Hasher>(verify_data, vbmeta_prop);
    } else if (vbmeta_prop.hash_alg == kSHA512) {
            verify_vbmeta_digest<SHA256Hasher>(verify_data, digest_);
    } else if (hash_alg_ == kSHA512) {
        std::tie(total_size, digest_matched) =
            verify_vbmeta_digest<SHA512Hasher>(verify_data, vbmeta_prop);
            verify_vbmeta_digest<SHA512Hasher>(verify_data, digest_);
    }

    if (total_size != vbmeta_prop.vbmeta_size) {
        LERROR << "total vbmeta size mismatch: " << total_size
               << " (expected: " << vbmeta_prop.vbmeta_size << ")";
    if (total_size != vbmeta_size_) {
        LERROR << "total vbmeta size mismatch: " << total_size << " (expected: " << vbmeta_size_
               << ")";
        return false;
    }

@@ -408,8 +425,7 @@ static bool get_hashtree_descriptor(const std::string& partition_name,
                continue;
            }
            if (desc.tag == AVB_DESCRIPTOR_TAG_HASHTREE) {
                desc_partition_name =
                    (const uint8_t*)descriptors[j] + sizeof(AvbHashtreeDescriptor);
                desc_partition_name = (const uint8_t*)descriptors[j] + sizeof(AvbHashtreeDescriptor);
                if (!avb_hashtree_descriptor_validate_and_byteswap(
                        (AvbHashtreeDescriptor*)descriptors[j], out_hashtree_desc)) {
                    continue;
@@ -441,134 +457,96 @@ static bool get_hashtree_descriptor(const std::string& partition_name,
    return true;
}

static bool init_is_avb_used() {
    // When AVB is used, boot loader should set androidboot.vbmeta.{hash_alg,
    // size, digest} in kernel cmdline or in device tree. They will then be
    // imported by init process to system properties: ro.boot.vbmeta.{hash_alg, size, digest}.
    //
    // In case of early mount, init properties are not initialized, so we also
    // ensure we look into kernel command line and device tree if the property is
    // not found
    //
    // Checks hash_alg as an indicator for whether AVB is used.
    // We don't have to parse and check all of them here. The check will
    // be done in fs_mgr_load_vbmeta_images() and FS_MGR_SETUP_AVB_FAIL will
    // be returned when there is an error.

    std::string hash_alg;
    if (!fs_mgr_get_boot_config("vbmeta.hash_alg", &hash_alg)) {
        return false;
    }
    if (hash_alg == "sha256" || hash_alg == "sha512") {
        return true;
    }
    return false;
}

bool fs_mgr_is_avb_used() {
    static bool result = init_is_avb_used();
    return result;
FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const std::string& device_file_by_name_prefix) {
    if (device_file_by_name_prefix.empty()) {
        LERROR << "Missing device file by-name prefix";
        return nullptr;
    }

int fs_mgr_load_vbmeta_images(struct fstab* fstab) {
    FS_MGR_CHECK(fstab != nullptr);

    // Gets the expected hash value of vbmeta images from
    // kernel cmdline.
    if (!load_vbmeta_prop(&fs_mgr_vbmeta_prop)) {
        return FS_MGR_SETUP_AVB_FAIL;
    // Gets the expected hash value of vbmeta images from kernel cmdline.
    std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create();
    if (!avb_verifier) {
        LERROR << "Failed to create FsManagerAvbVerifier";
        return nullptr;
    }

    fs_mgr_avb_ops = fs_mgr_dummy_avb_ops_new(fstab);
    if (fs_mgr_avb_ops == nullptr) {
        LERROR << "Failed to allocate dummy avb_ops";
        return FS_MGR_SETUP_AVB_FAIL;
    FsManagerAvbUniquePtr avb_handle(new FsManagerAvbHandle());
    if (!avb_handle) {
        LERROR << "Failed to allocate FsManagerAvbHandle";
        return nullptr;
    }

    // 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 fs_mgr_avb_verify_data, which is not required as
    // fs_mgr only deals with HASHTREE partitions.
    const char* requested_partitions[] = {nullptr};
    std::string ab_suffix = fs_mgr_get_slot_suffix();

    AvbSlotVerifyResult verify_result =
        avb_slot_verify(fs_mgr_avb_ops, requested_partitions, ab_suffix.c_str(),
                        fs_mgr_vbmeta_prop.allow_verification_error, &fs_mgr_avb_verify_data);
    FsManagerAvbOps avb_ops(device_file_by_name_prefix);
    AvbSlotVerifyResult verify_result = avb_ops.AvbSlotVerify(
        fs_mgr_get_slot_suffix(), avb_verifier->IsDeviceUnlocked(), &avb_handle->avb_slot_data_);

    // Only allow two verify results:
    //   - AVB_SLOT_VERIFY_RESULT_OK.
    //   - AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION (for UNLOCKED state).
    if (verify_result == AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION) {
        if (!fs_mgr_vbmeta_prop.allow_verification_error) {
        if (!avb_verifier->IsDeviceUnlocked()) {
            LERROR << "ERROR_VERIFICATION isn't allowed";
            goto fail;
            return nullptr;
        }
    } else if (verify_result != AVB_SLOT_VERIFY_RESULT_OK) {
        LERROR << "avb_slot_verify failed, result: " << verify_result;
        goto fail;
        return nullptr;
    }

    // Verifies vbmeta images against the digest passed from bootloader.
    if (!verify_vbmeta_images(*fs_mgr_avb_verify_data, fs_mgr_vbmeta_prop)) {
        LERROR << "verify_vbmeta_images failed";
        goto fail;
    if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
        LERROR << "VerifyVbmetaImages failed";
        return nullptr;
    } else {
        // Checks whether FLAGS_HASHTREE_DISABLED is set.
        AvbVBMetaImageHeader vbmeta_header;
        avb_vbmeta_image_header_to_host_byte_order(
            (AvbVBMetaImageHeader*)fs_mgr_avb_verify_data->vbmeta_images[0].vbmeta_data,
            (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
            &vbmeta_header);

        bool hashtree_disabled =
            ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
        if (hashtree_disabled) {
            return FS_MGR_SETUP_AVB_HASHTREE_DISABLED;
            avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled;
            return avb_handle;
        }
    }

    if (verify_result == AVB_SLOT_VERIFY_RESULT_OK) {
        return FS_MGR_SETUP_AVB_SUCCESS;
    }

fail:
    fs_mgr_unload_vbmeta_images();
    return FS_MGR_SETUP_AVB_FAIL;
        avb_handle->status_ = kFsManagerAvbHandleSuccess;
        return avb_handle;
    }

void fs_mgr_unload_vbmeta_images() {
    if (fs_mgr_avb_verify_data != nullptr) {
        avb_slot_verify_data_free(fs_mgr_avb_verify_data);
    return nullptr;
}

    if (fs_mgr_avb_ops != nullptr) {
        fs_mgr_dummy_avb_ops_free(fs_mgr_avb_ops);
    }
bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry) {
    if (!fstab_entry) return false;
    if (!avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) {
        return false;
    }

int fs_mgr_setup_avb(struct fstab_rec* fstab_entry) {
    if (!fstab_entry || !fs_mgr_avb_verify_data || fs_mgr_avb_verify_data->num_vbmeta_images < 1) {
        return FS_MGR_SETUP_AVB_FAIL;
    if (status_ == kFsManagerAvbHandleHashtreeDisabled) {
        LINFO << "AVB HASHTREE disabled on:" << fstab_entry->mount_point;
        return true;
    }
    if (status_ != kFsManagerAvbHandleSuccess) return false;

    std::string partition_name(basename(fstab_entry->mount_point));
    if (!avb_validate_utf8((const uint8_t*)partition_name.c_str(), partition_name.length())) {
        LERROR << "Partition name: " << partition_name.c_str() << " is not valid UTF-8.";
        return FS_MGR_SETUP_AVB_FAIL;
        return false;
    }

    AvbHashtreeDescriptor hashtree_descriptor;
    std::string salt;
    std::string root_digest;
    if (!get_hashtree_descriptor(partition_name, *fs_mgr_avb_verify_data, &hashtree_descriptor,
                                 &salt, &root_digest)) {
        return FS_MGR_SETUP_AVB_FAIL;
    if (!get_hashtree_descriptor(partition_name, *avb_slot_data_, &hashtree_descriptor, &salt,
                                 &root_digest)) {
        return false;
    }

    // Converts HASHTREE descriptor to verity_table_params.
    if (!hashtree_dm_verity_setup(fstab_entry, hashtree_descriptor, salt, root_digest)) {
        return FS_MGR_SETUP_AVB_FAIL;
        return false;
    }

    return FS_MGR_SETUP_AVB_SUCCESS;
    return true;
}
+76 −100

File changed.

Preview size limit exceeded, changes collapsed.

+30 −27
Original line number Diff line number Diff line
@@ -29,31 +29,34 @@

#include "fs_mgr.h"

__BEGIN_DECLS

/* Allocates a "dummy" AvbOps instance solely for use in user-space.
 * Returns nullptr on OOM.
 *
 * It mainly provides read_from_partitions() for user-space to get
 * AvbSlotVerifyData.vbmeta_images[] and the caller MUST check their
 * integrity against the androidboot.vbmeta.{hash_alg, size, digest}
 * values from /proc/cmdline, e.g. verify_vbmeta_images()
 * in fs_mgr_avb.cpp.
 *
 * Other I/O operations are only required in boot loader so we set
 * them as dummy operations here.
 *  - Will allow any public key for signing.
 *  - returns 0 for any rollback index location.
 *  - returns device is unlocked regardless of the actual state.
 *  - returns a dummy guid for any partition.
 *
 * Frees with fs_mgr_dummy_avb_ops_free().
 */
AvbOps* fs_mgr_dummy_avb_ops_new(struct fstab* fstab);

/* Frees an AvbOps instance previously allocated with fs_mgr_avb_ops_new(). */
void fs_mgr_dummy_avb_ops_free(AvbOps* ops);

__END_DECLS

// This class provides C++ bindings to interact with libavb, a small
// self-contained piece of code that's intended to be used in bootloaders.
// It mainly contains two functions:
//   - ReadFromPartition(): to read AVB metadata from a given partition.
//     It provides the implementation of AvbOps.read_from_partition() when
//     reading metadata through libavb.
//   - AvbSlotVerify(): the C++ binding of libavb->avb_slot_verify() to
//     read and verify the metadata and store it into the out_data parameter.
//     The caller MUST check the integrity of metadata against the
//     androidboot.vbmeta.{hash_alg, size, digest} values from /proc/cmdline.
//     e.g., see class FsManagerAvbVerifier for more details.
//
class FsManagerAvbOps {
  public:
    FsManagerAvbOps(const std::string& device_file_by_name_prefix);

    static FsManagerAvbOps* GetInstanceFromAvbOps(AvbOps* ops) {
        return reinterpret_cast<FsManagerAvbOps*>(ops->user_data);
    }

    AvbIOResult ReadFromPartition(const char* partition, int64_t offset, size_t num_bytes,
                                  void* buffer, size_t* out_num_read);

    AvbSlotVerifyResult AvbSlotVerify(const std::string& ab_suffix, bool allow_verification_error,
                                      AvbSlotVerifyData** out_data);

  private:
    AvbOps avb_ops_;
    std::string device_file_by_name_prefix_;
};
#endif /* __CORE_FS_MGR_AVB_OPS_H */
+63 −26

File changed.

Preview size limit exceeded, changes collapsed.

Loading