]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
x86: deliver SIGSEGV on user page faults
authorTulio A M Mendes <[email protected]>
Mon, 9 Feb 2026 22:57:17 +0000 (19:57 -0300)
committerTulio A M Mendes <[email protected]>
Mon, 9 Feb 2026 22:57:17 +0000 (19:57 -0300)
src/arch/x86/idt.c
user/init.c

index e90c41f3a7410185b809c6b502efc6848a6d1d02..f8373f2c1c2724b0ffaf41eb832d5f096bd15569 100644 (file)
@@ -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;
                 }
             }
 
index 8988b69f5615e0d28a5c90de588530ed2e734643..a7a0ef77cfff61bbe3eb8a895f7a9a3346162512 100644 (file)
@@ -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 {