|
@@ -14,6 +14,11 @@
|
|
#include <LibC/elf.h>
|
|
#include <LibC/elf.h>
|
|
#include <LibELF/Relocation.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
|
|
// Defined in the linker script
|
|
extern size_t __stack_chk_guard;
|
|
extern size_t __stack_chk_guard;
|
|
size_t __stack_chk_guard __attribute__((used));
|
|
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.
|
|
// This is where C++ execution begins, after boot.S transfers control here.
|
|
//
|
|
//
|
|
|
|
|
|
|
|
+u64 generate_secure_seed();
|
|
|
|
+
|
|
extern "C" [[noreturn]] void init()
|
|
extern "C" [[noreturn]] void init()
|
|
{
|
|
{
|
|
if (multiboot_info_ptr->mods_count < 1)
|
|
if (multiboot_info_ptr->mods_count < 1)
|
|
@@ -88,6 +95,10 @@ extern "C" [[noreturn]] void init()
|
|
#else
|
|
#else
|
|
FlatPtr kernel_load_base = 0x2000200000;
|
|
FlatPtr kernel_load_base = 0x2000200000;
|
|
#endif
|
|
#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;
|
|
FlatPtr kernel_load_end = 0;
|
|
for (size_t i = 0; i < kernel_elf_header.e_phnum; i++) {
|
|
for (size_t i = 0; i < kernel_elf_header.e_phnum; i++) {
|
|
@@ -201,7 +212,7 @@ extern "C" [[noreturn]] void init()
|
|
#if ARCH(I386)
|
|
#if ARCH(I386)
|
|
"add %0, %%esp"
|
|
"add %0, %%esp"
|
|
#else
|
|
#else
|
|
- "movabs %0, %%rax\n"
|
|
|
|
|
|
+ "mov %0, %%rax\n"
|
|
"add %%rax, %%rsp"
|
|
"add %%rax, %%rsp"
|
|
#endif
|
|
#endif
|
|
::"g"(kernel_mapping_base)
|
|
::"g"(kernel_mapping_base)
|
|
@@ -225,6 +236,31 @@ extern "C" [[noreturn]] void init()
|
|
__builtin_unreachable();
|
|
__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.
|
|
// Define some Itanium C++ ABI methods to stop the linker from complaining.
|
|
// If we actually call these something has gone horribly wrong
|
|
// If we actually call these something has gone horribly wrong
|
|
void* __dso_handle __attribute__((visibility("hidden")));
|
|
void* __dso_handle __attribute__((visibility("hidden")));
|