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

This commit is contained in:
Treehugger Robot 2019-09-25 15:50:05 +00:00 committed by Gerrit Code Review
commit e7180a796c
2 changed files with 43 additions and 9 deletions

View file

@ -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",

View file

@ -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) {