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

Commit 4ae3e510 authored by Bowgo Tsai's avatar Bowgo Tsai
Browse files

fs_mgr_avb: refactors how vbmeta is loaded

Adds two classes FsManagerAvbhandle and FsManagerAvbVerifier to replace the
following functions or struct:

    - fs_mgr_load_vbmeta_images() -> FsManagerAvbhandle::Open()
    - fs_mgr_unload_vbmeta_images() -> deleted
    - fs_mgr_setup_avb() -> FsManagerAvbhandle::SetUpAvb()

    - androidboot_vbmeta -> FsManagerAvbVerifier
    - load_vbmeta_prop() -> FsManagerAvbVerifier::Create()
    - verify_vbmeta_images() -> FsManagerAvbVerifier::VerifyVbmetaImages()

And only invokes FsManagerAvbhandle::Open() when there is a fstab entry having
'avb' flag (need HASHTREE descriptor). fs_mgr_is_avb_used() can be
removed as it only checks system property "ro.boot.vbmeta.hash_alg" to
decide whether vbmeta needs to be loaded, which might not be accurate.

For example, there are only HASH descriptors in the verified chain but
no HASHTREE descriptors. In this case, the fs_mgr doesn't have to do
anything because it only takes care of HASHTREE descriptors.

Also adds a new class FsManagerAvbOps to provide the C++ binding
FsManagerAvbOps::AvbSlotVerify() for libavb->avb_slot_verify().

Bug: 33254008
Test: test AVB on bullhead
Change-Id: I8fe15ba01c277152630a2a5c1c5c7f25fbf34030
Merged-In: I8fe15ba01c277152630a2a5c1c5c7f25fbf34030
(cherry picked from commit 95c966a8)
parent c1f9cbaf
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