lib/pe: Validate NumberOfRvaAndSizes and relocation block VirtualAddress
diff --git a/common/lib/pe.c b/common/lib/pe.c
index 06769149..4e95c135 100644
--- a/common/lib/pe.c
+++ b/common/lib/pe.c
@@ -331,6 +331,10 @@ again:
memcpy((void *)section_base, image + section->PointerToRawData, section_raw_size);
}
+ if (nt_hdrs->OptionalHeader.NumberOfRvaAndSizes < IMAGE_DIRECTORY_ENTRY_BASERELOC + 1) {
+ panic(true, "pe: NumberOfRvaAndSizes too small for import/reloc directories");
+ }
+
IMAGE_DATA_DIRECTORY *import_dir = &nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
IMAGE_DATA_DIRECTORY *reloc_dir = &nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
@@ -353,6 +357,10 @@ again:
panic(true, "pe: Invalid relocation block size");
}
+ if (block->VirtualAddress >= image_size) {
+ panic(true, "pe: Relocation block VirtualAddress out of bounds");
+ }
+
uintptr_t block_base = *physical_base + block->VirtualAddress;
size_t entries = (block->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION_BLOCK)) / sizeof(uint16_t);
uint16_t *relocs = (uint16_t *)(block + 1);
