Directly use FDT headers for detection

This commit is contained in:
topjohnwu 2019-02-21 05:24:05 -05:00
parent da3394f34e
commit 69d10b747a

View File

@ -77,6 +77,8 @@ int boot_img::parse_file(const char *image) {
exit(ELF32_RET); exit(ELF32_RET);
case ELF64: case ELF64:
exit(ELF64_RET); exit(ELF64_RET);
default:
break;
} }
} }
LOGE("No boot image magic found!\n"); LOGE("No boot image magic found!\n");
@ -180,28 +182,30 @@ int boot_img::parse_image(uint8_t *head) {
void boot_img::find_dtb() { void boot_img::find_dtb() {
for (uint32_t i = 0; i < hdr->kernel_size; ++i) { for (uint32_t i = 0; i < hdr->kernel_size; ++i) {
if (memcmp(kernel + i, DTB_MAGIC, 4)) auto fdt_hdr = reinterpret_cast<fdt_header *>(kernel + i);
if (fdt32_to_cpu(fdt_hdr->magic) != FDT_MAGIC)
continue; continue;
// Check that fdt_header.totalsize does not overflow kernel image size // Check that fdt_header.totalsize does not overflow kernel image size
uint32_t dt_sz = fdt32_to_cpu(*(uint32_t *)(kernel + i + 4)); uint32_t totalsize = fdt32_to_cpu(fdt_hdr->totalsize);
if (dt_sz > hdr->kernel_size - i) { if (totalsize > hdr->kernel_size - i) {
fprintf(stderr, "Invalid DTB detection at 0x%x: size (%u) > remaining (%u)\n", fprintf(stderr, "Invalid DTB detection at 0x%x: size (%u) > remaining (%u)\n",
i, dt_sz, hdr->kernel_size - i); i, totalsize, hdr->kernel_size - i);
continue; continue;
} }
// Check that fdt_header.off_dt_struct does not overflow kernel image size // Check that fdt_header.off_dt_struct does not overflow kernel image size
uint32_t dt_struct_offset = fdt32_to_cpu(*(uint32_t *)(kernel + i + 8)); uint32_t off_dt_struct = fdt32_to_cpu(fdt_hdr->off_dt_struct);
if (dt_struct_offset > hdr->kernel_size - i) { if (off_dt_struct > hdr->kernel_size - i) {
fprintf(stderr, "Invalid DTB detection at 0x%x: " fprintf(stderr, "Invalid DTB detection at 0x%x: "
"struct offset (%u) > remaining (%u)\n", "struct offset (%u) > remaining (%u)\n",
i, dt_struct_offset, hdr->kernel_size - i); i, off_dt_struct, hdr->kernel_size - i);
continue; continue;
} }
// Check that fdt_node_header.tag of first node is FDT_BEGIN_NODE // Check that fdt_node_header.tag of first node is FDT_BEGIN_NODE
uint32_t dt_begin_node = fdt32_to_cpu(*(uint32_t *)(kernel + i + dt_struct_offset)); auto fdt_node_hdr = reinterpret_cast<fdt_node_header *>(kernel + i + off_dt_struct);
if (dt_begin_node != FDT_BEGIN_NODE) { if (fdt32_to_cpu(fdt_node_hdr->tag) != FDT_BEGIN_NODE) {
fprintf(stderr, "Invalid DTB detection at 0x%x: " fprintf(stderr, "Invalid DTB detection at 0x%x: "
"header tag of first node != FDT_BEGIN_NODE\n", i); "header tag of first node != FDT_BEGIN_NODE\n", i);
continue; continue;