1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-11 18:20:43 +09:00

Kernel: Add an extremely primitive version of KASLR

This initial (and very basic) implementation of KASLR simply randomizes
the kernel base VA in the 256 MiB range following the default load base.
This commit is contained in:
Idan Horowitz 2022-03-21 22:59:48 +02:00 committed by Andreas Kling
parent a9764dabee
commit 1ad0e05ea1
Notes: sideshowbarker 2024-07-17 16:58:30 +09:00

View file

@ -14,6 +14,11 @@
#include <LibC/elf.h>
#include <LibELF/Relocation.h>
#if ARCH(I386) || ARCH(X86_64)
# include <Kernel/Arch/x86/ASM_wrapper.h>
# include <Kernel/Arch/x86/CPUID.h>
#endif
// Defined in the linker script
extern size_t __stack_chk_guard;
size_t __stack_chk_guard __attribute__((used));
@ -67,6 +72,8 @@ extern "C" [[noreturn]] void init();
// This is where C++ execution begins, after boot.S transfers control here.
//
u64 generate_secure_seed();
extern "C" [[noreturn]] void init()
{
if (multiboot_info_ptr->mods_count < 1)
@ -88,6 +95,10 @@ extern "C" [[noreturn]] void init()
#else
FlatPtr kernel_load_base = 0x2000200000;
#endif
// KASLR
static constexpr auto maximum_offset = 256 * MiB;
kernel_load_base = kernel_load_base + (generate_secure_seed() % maximum_offset);
kernel_load_base = kernel_load_base & ~(PAGE_SIZE - 1);
FlatPtr kernel_load_end = 0;
for (size_t i = 0; i < kernel_elf_header.e_phnum; i++) {
@ -201,7 +212,7 @@ extern "C" [[noreturn]] void init()
#if ARCH(I386)
"add %0, %%esp"
#else
"movabs %0, %%rax\n"
"mov %0, %%rax\n"
"add %%rax, %%rsp"
#endif
::"g"(kernel_mapping_base)
@ -225,6 +236,31 @@ extern "C" [[noreturn]] void init()
__builtin_unreachable();
}
u64 generate_secure_seed()
{
u32 seed = 0xFEEBDAED;
#if ARCH(I386) || ARCH(X86_64)
CPUID processor_info(0x1);
if (processor_info.edx() & (1 << 4)) // TSC
seed ^= read_tsc();
if (processor_info.ecx() & (1 << 30)) // RDRAND
seed ^= rdrand();
CPUID extended_features(0x7);
if (extended_features.ebx() & (1 << 18)) // RDSEED
seed ^= rdseed();
#else
# warning No native randomness source available for this architecture
#endif
seed ^= multiboot_info_ptr->mods_addr;
seed ^= multiboot_info_ptr->framebuffer_addr;
return seed;
}
// Define some Itanium C++ ABI methods to stop the linker from complaining.
// If we actually call these something has gone horribly wrong
void* __dso_handle __attribute__((visibility("hidden")));