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/docs/POSIX_ROADMAP.md?a=commitdiff_plain;h=85f3ed74345fb2afaac9326faf312db2019c653f;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 0000000..db2a470 --- /dev/null +++ b/include/kaslr.h @@ -0,0 +1,12 @@ +#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 9eacc64..c6972d6 100644 --- a/src/arch/x86/elf.c +++ b/src/arch/x86/elf.c @@ -278,9 +278,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 0000000..86f65fd --- /dev/null +++ b/src/kernel/kaslr.c @@ -0,0 +1,32 @@ +#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 b0f5dd0..2950c40 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -59,6 +59,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();