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:
parent
a9764dabee
commit
1ad0e05ea1
Notes:
sideshowbarker
2024-07-17 16:58:30 +09:00
Author: https://github.com/IdanHo
Commit: 1ad0e05ea1
Pull-request: https://github.com/SerenityOS/serenity/pull/13179
1 changed files with 37 additions and 1 deletions
|
@ -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")));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue