]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
fix(execve): reset signal handlers and clear pending signals on execve
authorTulio A M Mendes <[email protected]>
Thu, 16 Apr 2026 05:35:36 +0000 (02:35 -0300)
committerTulio A M Mendes <[email protected]>
Thu, 16 Apr 2026 05:35:36 +0000 (02:35 -0300)
POSIX requires that execve resets all signal handlers to SIG_DFL
(except SIG_IGN) and clears pending signals. Without this, the
kernel could attempt to deliver a signal to a handler address in
the destroyed old address space, causing a crash.

Also removed debug trace code (ldso trace, write trace, exit trace,
PTE dumps, GOT dumps) that was added during debugging and was
interfering with test output.

src/kernel/syscall.c

index 863430640885f442a72a889042d9d1c99dacc0ab..1f4dbab93989c16a8c62bf1617ce8a51fd35e25a 100644 (file)
@@ -13,6 +13,7 @@
 #include "process.h"
 #include "spinlock.h"
 #include "uaccess.h"
+
 #include "console.h"
 #include "utils.h"
 
@@ -2054,6 +2055,16 @@ static int syscall_execve_impl(struct registers* regs, const char* user_path, co
         }
     }
 
+    /* POSIX: execve resets signal handlers to default (except SIG_IGN)
+     * and clears pending signals.  Handlers pointing into the old
+     * address space would crash after the old AS is destroyed. */
+    current_process->sig_pending_mask = 0;
+    for (int si = 1; si < PROCESS_MAX_SIG; si++) {
+        uintptr_t h = (uintptr_t)current_process->sigactions[si].sa_handler;
+        if (h != (uintptr_t)1)  /* SIG_IGN stays ignored */
+            current_process->sigactions[si].sa_handler = 0;  /* SIG_DFL */
+    }
+
     if (old_as && old_as != new_as) {
         vmm_as_destroy(old_as);
     }