diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-07-20 02:32:53 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-20 15:12:19 +0200 |
commit | 56f952a5f2a282e6581d0c4de038eb0210c17b17 (patch) | |
tree | 549270d3cab044cf144b25198522e5eb083800c5 | |
parent | 51881853743ad380e78cc38883456d02c6c62da3 (diff) | |
download | serenity-56f952a5f2a282e6581d0c4de038eb0210c17b17.zip |
Prekernel: Don't assume that PT_LOAD headers are ordered by address
These headers are ordered by virtual address - at least with GCC - but
that might not always be the case.
-rw-r--r-- | Kernel/Prekernel/init.cpp | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/Kernel/Prekernel/init.cpp b/Kernel/Prekernel/init.cpp index 65ef94ac2f..85bcaba5d1 100644 --- a/Kernel/Prekernel/init.cpp +++ b/Kernel/Prekernel/init.cpp @@ -75,18 +75,26 @@ extern "C" [[noreturn]] void init() halt(); __builtin_memcpy(kernel_program_headers, kernel_image + kernel_elf_header.e_phoff, sizeof(ElfW(Phdr)) * kernel_elf_header.e_phnum); - FlatPtr kernel_load_base = kernel_program_headers[0].p_vaddr; - FlatPtr kernel_load_end = kernel_program_headers[kernel_elf_header.e_phnum - 1].p_vaddr + kernel_program_headers[kernel_elf_header.e_phnum - 1].p_memsz; + FlatPtr kernel_load_base, kernel_load_end; + for (size_t i = 0; i < kernel_elf_header.e_phnum; i++) { + auto& kernel_program_header = kernel_program_headers[i]; + if (kernel_program_header.p_type != PT_LOAD) + continue; + auto start = kernel_program_header.p_vaddr; + auto end = start + kernel_program_header.p_memsz; + if (start < (FlatPtr)end_of_prekernel_image) + halt(); + if (kernel_program_header.p_paddr < (FlatPtr)end_of_prekernel_image) + halt(); + if (kernel_load_base == 0 || start < kernel_load_base) + kernel_load_base = start; + if (end > kernel_load_end) + kernel_load_end = end; + } // align to 1GB kernel_load_base &= ~(FlatPtr)0x3fffffff; - if (kernel_program_headers[0].p_vaddr < (FlatPtr)end_of_prekernel_image) - halt(); - - if (kernel_program_headers[0].p_paddr < (FlatPtr)end_of_prekernel_image) - halt(); - #if ARCH(I386) int pdpt_flags = 0x1; #else |