]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
x86: treat user page fault as SIGSEGV
authorTulio A M Mendes <[email protected]>
Sun, 8 Feb 2026 03:56:13 +0000 (00:56 -0300)
committerTulio A M Mendes <[email protected]>
Sun, 8 Feb 2026 03:56:13 +0000 (00:56 -0300)
Handle ISR14 page faults from ring3 by terminating the current process with a SIGSEGV-like status (128+11) instead of kernel panic. Add userland smoke test that triggers a NULL write and validates waitpid status.

src/arch/x86/idt.c
user/init.c

index 9db3e068bc9876ebb6a5fa8fbb4068dddd01eb5d..aa0d2570aab1d6f808f1e2852e25e301a840410c 100644 (file)
@@ -1,6 +1,7 @@
 #include "idt.h"
 #include "io.h"
 #include "uart_console.h"
+#include "process.h"
 #include "spinlock.h"
 #include <stddef.h>
 
@@ -171,6 +172,17 @@ void isr_handler(struct registers* regs) {
     } else {
         // 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 ((regs->cs & 3U) == 3U) {
+                    const int SIG_SEGV = 11;
+                    process_exit_notify(128 + SIG_SEGV);
+                    __asm__ volatile("sti");
+                    schedule();
+                    for (;;) __asm__ volatile("hlt");
+                }
+            }
+
             __asm__ volatile("cli"); // Stop everything
             
             uart_print("\n\n!!! KERNEL PANIC !!!\n");
index aa7b77badc02198a77064741479acb9103f61dfb..0d745592dc27c45bfb9ea0f2989b37fbb3655698 100644 (file)
@@ -35,6 +35,7 @@ enum {
 
 enum {
     SIGKILL = 9,
+    SIGSEGV = 11,
 };
 
 enum {
@@ -823,6 +824,32 @@ void _start(void) {
         }
     }
 
+    {
+        int pid = sys_fork();
+        if (pid < 0) {
+            static const char msg[] = "[init] sigsegv test fork failed\n";
+            (void)sys_write(1, msg, (uint32_t)(sizeof(msg) - 1));
+            sys_exit(1);
+        }
+
+        if (pid == 0) {
+            volatile uint32_t* p = (volatile uint32_t*)0;
+            *p = 1;
+            sys_exit(1);
+        }
+
+        int st = 0;
+        int wp = sys_waitpid(pid, &st, 0);
+        if (wp == pid && st == (128 + SIGSEGV)) {
+            static const char msg[] = "[init] SIGSEGV OK\n";
+            (void)sys_write(1, msg, (uint32_t)(sizeof(msg) - 1));
+        } else {
+            static const char msg[] = "[init] SIGSEGV failed\n";
+            (void)sys_write(1, msg, (uint32_t)(sizeof(msg) - 1));
+            sys_exit(1);
+        }
+    }
+
     int ok = 1;
     for (int i = 0; i < NCHILD; i++) {
         int st = 0;