From: Tulio A M Mendes Date: Thu, 12 Feb 2026 04:47:34 +0000 (-0300) Subject: feat: ASLR — TSC-seeded xorshift32 PRNG randomizes user stack base by up to 1MB per... X-Git-Url: https://projects.tadryanom.me/?a=commitdiff_plain;h=91e4769025df3095157b63e22a8485d9d0e71fbf;p=AdrOS.git feat: ASLR — TSC-seeded xorshift32 PRNG randomizes user stack base by up to 1MB per execve --- diff --git a/include/kaslr.h b/include/kaslr.h new file mode 100644 index 00000000..a3dd126b --- /dev/null +++ b/include/kaslr.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2018, Tulio A M Mendes + * All rights reserved. + * See LICENSE for details. + * + * Source: https://github.com/tadryanom/AdrOS + */ + +#ifndef KASLR_H +#define KASLR_H + +#include + +void kaslr_init(void); +uint32_t kaslr_rand(void); + +/* Returns a page-aligned random offset in [0, max_pages * PAGE_SIZE). */ +uint32_t kaslr_offset(uint32_t max_pages); + +#endif diff --git a/src/arch/x86/elf.c b/src/arch/x86/elf.c index 2243ce9b..e830680b 100644 --- a/src/arch/x86/elf.c +++ b/src/arch/x86/elf.c @@ -287,9 +287,12 @@ int elf32_load_user_from_initrd(const char* filename, uintptr_t* entry_out, uint (void)has_interp; /* 32 KB user stack with a 4 KB guard page below (unmapped). - * Guard page at 0x007FF000 is left unmapped so stack overflow - * triggers a page fault → SIGSEGV instead of silent corruption. */ - const uintptr_t user_stack_base = 0x00800000U; + * Guard page at stack_base - 0x1000 is left unmapped so stack overflow + * triggers a page fault → SIGSEGV instead of silent corruption. + * ASLR: randomize stack base by up to 256 pages (1 MB). */ + extern uint32_t kaslr_offset(uint32_t max_pages); + const uintptr_t aslr_stack_slide = kaslr_offset(256); + const uintptr_t user_stack_base = 0x00800000U + aslr_stack_slide; const size_t user_stack_size = 0x8000; /* 8 pages = 32 KB */ int src2 = elf32_map_user_range(new_as, user_stack_base, user_stack_size, VMM_FLAG_RW); diff --git a/src/kernel/kaslr.c b/src/kernel/kaslr.c new file mode 100644 index 00000000..d2926c38 --- /dev/null +++ b/src/kernel/kaslr.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2018, Tulio A M Mendes + * All rights reserved. + * See LICENSE for details. + * + * Source: https://github.com/tadryanom/AdrOS + */ + +#include "kaslr.h" +#include "uart_console.h" + +static uint32_t prng_state; + +static inline uint64_t rdtsc(void) { + uint32_t lo, hi; + __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi)); + return ((uint64_t)hi << 32) | lo; +} + +void kaslr_init(void) { + uint64_t tsc = rdtsc(); + prng_state = (uint32_t)(tsc ^ (tsc >> 32)); + if (prng_state == 0) prng_state = 0xDEADBEEF; + uart_print("[KASLR] PRNG seeded from TSC\n"); +} + +uint32_t kaslr_rand(void) { + /* xorshift32 */ + uint32_t x = prng_state; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + prng_state = x; + return x; +} + +uint32_t kaslr_offset(uint32_t max_pages) { + if (max_pages == 0) return 0; + return (kaslr_rand() % max_pages) * 0x1000U; +} diff --git a/src/kernel/main.c b/src/kernel/main.c index 75a80ecb..5a6cb97c 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -68,6 +68,12 @@ void kernel_main(const struct boot_info* bi) { // 5. Initialize Shared Memory IPC shm_init(); + // 6b. Initialize KASLR PRNG + { + extern void kaslr_init(void); + kaslr_init(); + } + // 7. Initialize Multitasking kprintf("[AdrOS] Initializing Scheduler...\n"); process_init();