From 153700e5d824c09a0d2c84f1e001d4ca3b7544f9 Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Mon, 9 Feb 2026 19:57:17 -0300 Subject: [PATCH] x86: deliver SIGSEGV on user page faults --- src/arch/x86/idt.c | 13 ++++++++----- user/init.c | 31 ++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/arch/x86/idt.c b/src/arch/x86/idt.c index e90c41f..f8373f2 100644 --- a/src/arch/x86/idt.c +++ b/src/arch/x86/idt.c @@ -284,13 +284,16 @@ void isr_handler(struct registers* regs) { // If Exception (0-31), Panic if (regs->int_no < 32) { if (regs->int_no == 14) { - // If page fault came from ring3, treat it as a SIGSEGV-like fatal event. + // If page fault came from ring3, convert it into a SIGSEGV delivery. + // Default action for SIGSEGV will terminate the process, but a user + // handler installed via sigaction() must be respected. if ((regs->cs & 3U) == 3U) { const int SIG_SEGV = 11; - process_exit_notify(128 + SIG_SEGV); - __asm__ volatile("sti"); - schedule(); - for (;;) __asm__ volatile("hlt"); + if (current_process) { + current_process->sig_pending_mask |= (1U << (uint32_t)SIG_SEGV); + } + deliver_signals_to_usermode(regs); + return; } } diff --git a/user/init.c b/user/init.c index 8988b69..a7a0ef7 100644 --- a/user/init.c +++ b/user/init.c @@ -423,7 +423,9 @@ __attribute__((noreturn)) static void sys_exit(int code) { : "a"(SYSCALL_EXIT), "b"(code) : "memory" ); - __builtin_unreachable(); + for (;;) { + __asm__ volatile("hlt"); + } } static volatile int got_usr1 = 0; @@ -453,6 +455,13 @@ static void ttou_handler(int sig) { got_ttou = 1; } +static void sigsegv_exit_handler(int sig) { + (void)sig; + static const char msg[] = "[init] SIGSEGV handler invoked\n"; + (void)sys_write(1, msg, (uint32_t)(sizeof(msg) - 1)); + sys_exit(0); +} + void _start(void) { __asm__ volatile( "mov $0x23, %ax\n" @@ -998,11 +1007,10 @@ void _start(void) { (uint32_t)(sizeof("[init] setsid test: before fork\n") - 1)); int pid = sys_fork(); if (pid < 0) { - sys_write(1, "[init] setsid test fork failed\n", - (uint32_t)(sizeof("[init] setsid test fork failed\n") - 1)); - sys_exit(1); + static const char smsg[] = "[init] fork failed\n"; + (void)sys_write(1, smsg, (uint32_t)(sizeof(smsg) - 1)); + sys_exit(2); } - if (pid == 0) { sys_write(1, "[init] setsid test: child start\n", (uint32_t)(sizeof("[init] setsid test: child start\n") - 1)); @@ -1377,14 +1385,19 @@ void _start(void) { } if (pid == 0) { - volatile uint32_t* p = (volatile uint32_t*)0; - *p = 1; - sys_exit(1); + if (sys_sigaction(SIGSEGV, sigsegv_exit_handler, 0) < 0) { + static const char msg[] = "[init] sigaction(SIGSEGV) failed\n"; + (void)sys_write(1, msg, (uint32_t)(sizeof(msg) - 1)); + sys_exit(1); + } + + *(volatile uint32_t*)0x0 = 123; + sys_exit(2); } int st = 0; int wp = sys_waitpid(pid, &st, 0); - if (wp == pid && st == (128 + SIGSEGV)) { + if (wp == pid && st == 0) { static const char msg[] = "[init] SIGSEGV OK\n"; (void)sys_write(1, msg, (uint32_t)(sizeof(msg) - 1)); } else { -- 2.43.0