Loading fastboot/Android.bp +5 −1 Original line number Diff line number Diff line Loading @@ -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", Loading fastboot/fastboot.cpp +38 −8 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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"); } Loading @@ -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) { Loading Loading
fastboot/Android.bp +5 −1 Original line number Diff line number Diff line Loading @@ -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", Loading
fastboot/fastboot.cpp +38 −8 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading Loading @@ -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"); } Loading @@ -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) { Loading