From 1e490f032ef1c3fab7d63e0978a7c6a1b7f438ec Mon Sep 17 00:00:00 2001 From: Keith Mok Date: Sat, 4 Jun 2022 16:58:04 +0000 Subject: [PATCH] fastboot: vendor boot img util OOB If vendor image size is less than what the header claims, there is OOB access. And it did not check page size equal to zero also. Bug: 234208198 Test: fastboot_fuzzer Change-Id: Iec08acf9bb354db4c4cd25e3a0c581974fee7eed --- fastboot/vendor_boot_img_utils.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fastboot/vendor_boot_img_utils.cpp b/fastboot/vendor_boot_img_utils.cpp index 9e09abbd1..9f05253c0 100644 --- a/fastboot/vendor_boot_img_utils.cpp +++ b/fastboot/vendor_boot_img_utils.cpp @@ -152,6 +152,9 @@ class DataUpdater { if (memcmp(hdr->magic, VENDOR_BOOT_MAGIC, VENDOR_BOOT_MAGIC_SIZE) != 0) { return Errorf("Vendor boot image magic mismatch"); } + if (hdr->page_size == 0) { + return Errorf("Page size cannot be zero"); + } if (hdr->header_version < version) { return Errorf("Require vendor boot header V{} but is V{}", version, hdr->header_version); } @@ -199,6 +202,7 @@ class DataUpdater { } // round |value| up to a multiple of |page_size|. +// aware that this can be integer overflow if value is too large inline uint32_t round_up(uint32_t value, uint32_t page_size) { return (value + page_size - 1) / page_size * page_size; } @@ -311,7 +315,13 @@ inline uint32_t round_up(uint32_t value, uint32_t page_size) { const uint32_t r = round_up(hdr->vendor_ramdisk_table_size, hdr->page_size); const uint32_t s = round_up(hdr->bootconfig_size, hdr->page_size); - if (hdr->vendor_ramdisk_table_entry_num == std::numeric_limits::max()) { + uint64_t total_size = (uint64_t)o + p + q + r + s; + if (total_size > vendor_boot.size()) { + return Errorf("Vendor boot image size is too small, overflow"); + } + + if ((uint64_t)hdr->vendor_ramdisk_table_entry_num * sizeof(vendor_ramdisk_table_entry_v4) > + (uint64_t)o + p + q + r) { return Errorf("Too many vendor ramdisk entries in table, overflow"); }