:: commit 5dd725dbababe5b2e13b3ada7d6b45d26eb58a30

mintsuki <mintsuki@protonmail.com> — 2022-03-13 16:46

parents: ee1b9f19a1

elf: Add more sanity checks

diff --git a/common/lib/elf.c b/common/lib/elf.c
index ceefb352..63a5d301 100644
--- a/common/lib/elf.c
+++ b/common/lib/elf.c
@@ -117,6 +117,10 @@ int elf_bits(uint8_t *elf) {
 }
 
 static bool elf64_is_relocatable(uint8_t *elf, struct elf64_hdr *hdr) {
+    if (hdr->phdr_size < sizeof(struct elf64_phdr)) {
+        panic(true, "elf: phdr_size < sizeof(struct elf64_phdr)");
+    }
+
     // Find DYN segment
     for (uint16_t i = 0; i < hdr->ph_num; i++) {
         struct elf64_phdr phdr;
@@ -131,6 +135,10 @@ static bool elf64_is_relocatable(uint8_t *elf, struct elf64_hdr *hdr) {
 }
 
 static int elf64_apply_relocations(uint8_t *elf, struct elf64_hdr *hdr, void *buffer, uint64_t vaddr, size_t size, uint64_t slide) {
+    if (hdr->phdr_size < sizeof(struct elf64_phdr)) {
+        panic(true, "elf: phdr_size < sizeof(struct elf64_phdr)");
+    }
+
     // Find DYN segment
     for (uint16_t i = 0; i < hdr->ph_num; i++) {
         struct elf64_phdr phdr;
@@ -235,9 +243,13 @@ int elf64_load_section(uint8_t *elf, void *buffer, const char *name, size_t limi
         return 1;
     }
 
+    if (hdr.shdr_size < sizeof(struct elf64_shdr)) {
+        panic(true, "elf: shdr_size < sizeof(struct elf64_shdr)");
+    }
+
     struct elf64_shdr shstrtab;
     memcpy(&shstrtab, elf + (hdr.shoff + hdr.shstrndx * hdr.shdr_size),
-            sizeof(struct elf64_shdr));
+           sizeof(struct elf64_shdr));
 
     char *names = ext_mem_alloc(shstrtab.sh_size);
     memcpy(names, elf + (shstrtab.sh_offset), shstrtab.sh_size);
@@ -329,6 +341,10 @@ int elf32_load_section(uint8_t *elf, void *buffer, const char *name, size_t limi
         return 1;
     }
 
+    if (hdr.shdr_size < sizeof(struct elf32_shdr)) {
+        panic(true, "elf: shdr_size < sizeof(struct elf32_shdr)");
+    }
+
     struct elf32_shdr shstrtab;
     memcpy(&shstrtab, elf + (hdr.shoff + hdr.shstrndx * hdr.shdr_size),
            sizeof(struct elf32_shdr));
@@ -372,6 +388,10 @@ static uint64_t elf64_max_align(uint8_t *elf) {
     struct elf64_hdr hdr;
     memcpy(&hdr, elf + (0), sizeof(struct elf64_hdr));
 
+    if (hdr.phdr_size < sizeof(struct elf64_phdr)) {
+        panic(true, "elf: phdr_size < sizeof(struct elf64_phdr)");
+    }
+
     for (uint16_t i = 0; i < hdr.ph_num; i++) {
         struct elf64_phdr phdr;
         memcpy(&phdr, elf + (hdr.phoff + i * hdr.phdr_size),
@@ -398,6 +418,10 @@ static void elf64_get_ranges(uint8_t *elf, uint64_t slide, bool use_paddr, struc
 
     uint64_t ranges_count = 0;
 
+    if (hdr.phdr_size < sizeof(struct elf64_phdr)) {
+        panic(true, "elf: phdr_size < sizeof(struct elf64_phdr)");
+    }
+
     for (uint16_t i = 0; i < hdr.ph_num; i++) {
         struct elf64_phdr phdr;
         memcpy(&phdr, elf + (hdr.phoff + i * hdr.phdr_size),
@@ -484,6 +508,10 @@ int elf64_load(uint8_t *elf, uint64_t *entry_point, uint64_t *top, uint64_t *_sl
 
     uint64_t image_size = 0;
 
+    if (hdr.phdr_size < sizeof(struct elf64_phdr)) {
+        panic(true, "elf: phdr_size < sizeof(struct elf64_phdr)");
+    }
+
     if (fully_virtual) {
         simulation = false;
 
@@ -686,6 +714,10 @@ int elf32_load(uint8_t *elf, uint32_t *entry_point, uint32_t *top, uint32_t allo
     if (top)
         *top = 0;
 
+    if (hdr.phdr_size < sizeof(struct elf32_phdr)) {
+        panic(true, "elf: phdr_size < sizeof(struct elf32_phdr)");
+    }
+
     for (uint16_t i = 0; i < hdr.ph_num; i++) {
         struct elf32_phdr phdr;
         memcpy(&phdr, elf + (hdr.phoff + i * hdr.phdr_size),
@@ -694,6 +726,11 @@ int elf32_load(uint8_t *elf, uint32_t *entry_point, uint32_t *top, uint32_t allo
         if (phdr.p_type != PT_LOAD)
             continue;
 
+        // Sanity checks
+        if (phdr.p_filesz > phdr.p_memsz) {
+            panic(true, "elf: p_filesz > p_memsz");
+        }
+
         if (top) {
             uint32_t this_top = phdr.p_paddr + phdr.p_memsz;
             if (this_top > *top) {
tab: 248 wrap: offon