--- /dev/null
+#ifndef KASLR_H
+#define KASLR_H
+
+#include <stdint.h>
+
+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
(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);
--- /dev/null
+#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;
+}
// 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();