summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-07-20 02:32:53 +0200
committerAndreas Kling <kling@serenityos.org>2021-07-20 15:12:19 +0200
commit56f952a5f2a282e6581d0c4de038eb0210c17b17 (patch)
tree549270d3cab044cf144b25198522e5eb083800c5 /Kernel
parent51881853743ad380e78cc38883456d02c6c62da3 (diff)
downloadserenity-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.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Prekernel/init.cpp24
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