diff --git a/Kernel/Prekernel/init.cpp b/Kernel/Prekernel/init.cpp index c28931a444..01ae0629d4 100644 --- a/Kernel/Prekernel/init.cpp +++ b/Kernel/Prekernel/init.cpp @@ -14,6 +14,11 @@ #include #include +#if ARCH(I386) || ARCH(X86_64) +# include +# include +#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")));