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

Commit 8665bb74 authored by Chin-Ting Kuo's avatar Chin-Ting Kuo Committed by android-build-merger
Browse files

Merge "Allow --disable-verification when top-level vbmeta is in 'boot'"

am: e7180a79

Change-Id: I084dc179167d82f4b1733d2a9b75c5c583f0f62d
parents d3de6487 e7180a79
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -189,7 +189,11 @@ cc_defaults {
    // will violate ODR.
    shared_libs: [],

    header_libs: ["bootimg_headers"],
    header_libs: [
        "avb_headers",
        "bootimg_headers",
    ],

    static_libs: [
        "libziparchive",
        "libsparse",
+38 −8
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
#include <utility>
#include <vector>

#include <android-base/endian.h>
#include <android-base/file.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
@@ -59,6 +60,7 @@
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <build/version.h>
#include <libavb/libavb.h>
#include <liblp/liblp.h>
#include <platform_tools_version.h>
#include <sparse/sparse.h>
@@ -919,33 +921,50 @@ static bool load_buf(const char* fname, struct fastboot_buffer* buf) {
    return load_buf_fd(fd.release(), buf);
}

static void rewrite_vbmeta_buffer(struct fastboot_buffer* buf) {
static void rewrite_vbmeta_buffer(struct fastboot_buffer* buf, bool vbmeta_in_boot) {
    // Buffer needs to be at least the size of the VBMeta struct which
    // is 256 bytes.
    if (buf->sz < 256) {
        return;
    }

    int fd = make_temporary_fd("vbmeta rewriting");

    std::string data;
    if (!android::base::ReadFdToString(buf->fd, &data)) {
        die("Failed reading from vbmeta");
    }

    uint64_t vbmeta_offset = 0;
    if (vbmeta_in_boot) {
        // Tries to locate top-level vbmeta from boot.img footer.
        uint64_t footer_offset = buf->sz - AVB_FOOTER_SIZE;
        if (0 != data.compare(footer_offset, AVB_FOOTER_MAGIC_LEN, AVB_FOOTER_MAGIC)) {
            die("Failed to find AVB_FOOTER at offset: %" PRId64, footer_offset);
        }
        const AvbFooter* footer = reinterpret_cast<const AvbFooter*>(data.c_str() + footer_offset);
        vbmeta_offset = be64toh(footer->vbmeta_offset);
    }
    // Ensures there is AVB_MAGIC at vbmeta_offset.
    if (0 != data.compare(vbmeta_offset, AVB_MAGIC_LEN, AVB_MAGIC)) {
        die("Failed to find AVB_MAGIC at offset: %" PRId64, vbmeta_offset);
    }

    fprintf(stderr, "Rewriting vbmeta struct at offset: %" PRId64 "\n", vbmeta_offset);

    // There's a 32-bit big endian |flags| field at offset 120 where
    // bit 0 corresponds to disable-verity and bit 1 corresponds to
    // disable-verification.
    //
    // See external/avb/libavb/avb_vbmeta_image.h for the layout of
    // the VBMeta struct.
    uint64_t flags_offset = 123 + vbmeta_offset;
    if (g_disable_verity) {
        data[123] |= 0x01;
        data[flags_offset] |= 0x01;
    }
    if (g_disable_verification) {
        data[123] |= 0x02;
        data[flags_offset] |= 0x02;
    }

    int fd = make_temporary_fd("vbmeta rewriting");
    if (!android::base::WriteStringToFd(data, fd)) {
        die("Failed writing to modified vbmeta");
    }
@@ -954,14 +973,25 @@ static void rewrite_vbmeta_buffer(struct fastboot_buffer* buf) {
    lseek(fd, 0, SEEK_SET);
}

static bool has_vbmeta_partition() {
    std::string partition_type;
    return fb->GetVar("partition-type:vbmeta", &partition_type) == fastboot::SUCCESS ||
           fb->GetVar("partition-type:vbmeta_a", &partition_type) == fastboot::SUCCESS ||
           fb->GetVar("partition-type:vbmeta_b", &partition_type) == fastboot::SUCCESS;
}

static void flash_buf(const std::string& partition, struct fastboot_buffer *buf)
{
    sparse_file** s;

    // Rewrite vbmeta if that's what we're flashing and modification has been requested.
    if ((g_disable_verity || g_disable_verification) &&
        (partition == "vbmeta" || partition == "vbmeta_a" || partition == "vbmeta_b")) {
        rewrite_vbmeta_buffer(buf);
    if (g_disable_verity || g_disable_verification) {
        if (partition == "vbmeta" || partition == "vbmeta_a" || partition == "vbmeta_b") {
            rewrite_vbmeta_buffer(buf, false /* vbmeta_in_boot */);
        } else if (!has_vbmeta_partition() &&
                   (partition == "boot" || partition == "boot_a" || partition == "boot_b")) {
            rewrite_vbmeta_buffer(buf, true /* vbmeta_in_boot */ );
        }
    }

    switch (buf->type) {