From f0166efe8c92359079dcff1e077e9e1615260007 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Tue, 22 Mar 2022 19:10:17 +0200 Subject: [PATCH] Kernel: Use the whole kernel PD range when randomizing the KASLR offset Now that we reclaim the memory range that is created by KASLR before the start of the kernel image, there's no need to be conservative with the KASLR offset. --- Kernel/BootInfo.h | 1 - Kernel/Memory/PageDirectory.cpp | 3 ++- Kernel/Prekernel/Prekernel.h | 2 +- Kernel/Prekernel/init.cpp | 3 +-- Kernel/Sections.h | 2 +- Kernel/init.cpp | 2 -- 6 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Kernel/BootInfo.h b/Kernel/BootInfo.h index 94bdbb3d1d..48330cce7d 100644 --- a/Kernel/BootInfo.h +++ b/Kernel/BootInfo.h @@ -18,7 +18,6 @@ extern "C" PhysicalAddress start_of_prekernel_image; extern "C" PhysicalAddress end_of_prekernel_image; extern "C" size_t physical_to_virtual_offset; extern "C" FlatPtr kernel_mapping_base; -extern "C" FlatPtr default_kernel_load_base; extern "C" FlatPtr kernel_load_base; #if ARCH(X86_64) extern "C" u32 gdt64ptr; diff --git a/Kernel/Memory/PageDirectory.cpp b/Kernel/Memory/PageDirectory.cpp index 6da3d97434..dc0a652860 100644 --- a/Kernel/Memory/PageDirectory.cpp +++ b/Kernel/Memory/PageDirectory.cpp @@ -36,7 +36,8 @@ UNMAP_AFTER_INIT NonnullRefPtr PageDirectory::must_create_kernel_ { auto directory = adopt_ref_if_nonnull(new (nothrow) PageDirectory).release_nonnull(); - MUST(directory->m_range_allocator.initialize_with_range(VirtualAddress(default_kernel_load_base), KERNEL_PD_END - default_kernel_load_base)); + auto kernel_range_start = kernel_mapping_base + 2 * MiB; // The first 2 MiB are used for mapping the pre-kernel + MUST(directory->m_range_allocator.initialize_with_range(VirtualAddress(kernel_range_start), KERNEL_PD_END - kernel_range_start)); // Carve out the whole page directory covering the kernel image to make MemoryManager::initialize_physical_pages() happy FlatPtr start_of_range = ((FlatPtr)start_of_kernel_image & ~(FlatPtr)0x1fffff); FlatPtr end_of_range = ((FlatPtr)end_of_kernel_image & ~(FlatPtr)0x1fffff) + 0x200000; diff --git a/Kernel/Prekernel/Prekernel.h b/Kernel/Prekernel/Prekernel.h index b01f5eeb66..f237286e2f 100644 --- a/Kernel/Prekernel/Prekernel.h +++ b/Kernel/Prekernel/Prekernel.h @@ -13,6 +13,7 @@ #endif #define MAX_KERNEL_SIZE 0x4000000 +#define KERNEL_PD_SIZE 0x31000000 #ifdef __cplusplus namespace Kernel { @@ -22,7 +23,6 @@ struct [[gnu::packed]] BootInfo { u32 end_of_prekernel_image; u64 physical_to_virtual_offset; u64 kernel_mapping_base; - u64 default_kernel_load_base; u64 kernel_load_base; # if ARCH(X86_64) u32 gdt64ptr; diff --git a/Kernel/Prekernel/init.cpp b/Kernel/Prekernel/init.cpp index 3692998cfc..26a4c4d95a 100644 --- a/Kernel/Prekernel/init.cpp +++ b/Kernel/Prekernel/init.cpp @@ -97,7 +97,7 @@ extern "C" [[noreturn]] void init() #endif // KASLR - static constexpr auto maximum_offset = 256 * MiB; + FlatPtr maximum_offset = (FlatPtr)KERNEL_PD_SIZE - MAX_KERNEL_SIZE - 2 * MiB; // The first 2 MiB are used for mapping the pre-kernel FlatPtr kernel_load_base = default_kernel_load_base + (generate_secure_seed() % maximum_offset); kernel_load_base &= ~(2 * MiB - 1); @@ -184,7 +184,6 @@ extern "C" [[noreturn]] void init() info.end_of_prekernel_image = (PhysicalPtr)end_of_prekernel_image; info.physical_to_virtual_offset = kernel_load_base - kernel_physical_base; info.kernel_mapping_base = kernel_mapping_base; - info.default_kernel_load_base = default_kernel_load_base; info.kernel_load_base = kernel_load_base; #if ARCH(X86_64) info.gdt64ptr = (PhysicalPtr)gdt64ptr; diff --git a/Kernel/Sections.h b/Kernel/Sections.h index 61332bde08..5ea5638689 100644 --- a/Kernel/Sections.h +++ b/Kernel/Sections.h @@ -15,7 +15,7 @@ #define READONLY_AFTER_INIT __attribute__((section(".ro_after_init"))) #define UNMAP_AFTER_INIT NEVER_INLINE __attribute__((section(".unmap_after_init"))) -#define KERNEL_PD_END (kernel_mapping_base + 0x31000000) +#define KERNEL_PD_END (kernel_mapping_base + KERNEL_PD_SIZE) #define KERNEL_PT1024_BASE (kernel_mapping_base + 0x3FE00000) #define KERNEL_QUICKMAP_PT (KERNEL_PT1024_BASE + 0x6000) #define KERNEL_QUICKMAP_PD (KERNEL_PT1024_BASE + 0x7000) diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 8af64861fd..c49a4ea339 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -117,7 +117,6 @@ READONLY_AFTER_INIT PhysicalAddress start_of_prekernel_image; READONLY_AFTER_INIT PhysicalAddress end_of_prekernel_image; READONLY_AFTER_INIT size_t physical_to_virtual_offset; READONLY_AFTER_INIT FlatPtr kernel_mapping_base; -READONLY_AFTER_INIT FlatPtr default_kernel_load_base; READONLY_AFTER_INIT FlatPtr kernel_load_base; #if ARCH(X86_64) READONLY_AFTER_INIT PhysicalAddress boot_pml4t; @@ -150,7 +149,6 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info) end_of_prekernel_image = PhysicalAddress { boot_info.end_of_prekernel_image }; physical_to_virtual_offset = boot_info.physical_to_virtual_offset; kernel_mapping_base = boot_info.kernel_mapping_base; - default_kernel_load_base = boot_info.default_kernel_load_base; kernel_load_base = boot_info.kernel_load_base; #if ARCH(X86_64) gdt64ptr = boot_info.gdt64ptr;