From 310876dcec69978b5198bafa2abe246ea79cfdec Mon Sep 17 00:00:00 2001 From: Erik van der Kouwe Date: Sun, 31 Jan 2010 19:13:20 +0000 Subject: [PATCH] Kill processes which ignore signals thatshould not be ignored --- man/man2/sigaction.2 | 17 +++++++++++------ servers/pm/glo.h | 1 + servers/pm/main.c | 5 +++++ servers/pm/signal.c | 18 ++++++++++++------ test/test5.c | 8 ++++---- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/man/man2/sigaction.2 b/man/man2/sigaction.2 index 9c1fa71fd..91ee36df4 100644 --- a/man/man2/sigaction.2 +++ b/man/man2/sigaction.2 @@ -130,19 +130,19 @@ signal num notes description SIGHUP 1 km Hangup SIGINT 2 k Interrupt (usually DEL or CTRL\-C) SIGQUIT 3 kcm Quit (usually CTRL\-\e) -SIGILL 4 kc Illegal instruction -SIGTRAP 5 kc Trace trap +SIGILL 4 Kc Illegal instruction +SIGTRAP 5 Kc Trace trap SIGABRT 6 kcm Abort program -SIGBUS 7 kc Bus error -SIGFPE 8 kc Floating point exception +SIGBUS 7 Kc Bus error +SIGFPE 8 Kc Floating point exception SIGKILL 9 k Kill SIGUSR1 10 k User defined signal #1 -SIGSEGV 11 kc Segmentation fault +SIGSEGV 11 Kc Segmentation fault SIGUSR2 12 k User defined signal #2 SIGPIPE 13 k Write to a pipe with no reader SIGALRM 14 k Alarm clock SIGTERM 15 km Terminate (default for kill(1)) -SIGEMT 16 xkc Emulator trap +SIGEMT 16 xKc Emulator trap SIGCHLD 17 pi Child process terminated SIGCONT 18 pi Continue if stopped SIGSTOP 19 ps Stop signal @@ -161,6 +161,11 @@ The letters in the notes column indicate: .B k The process is killed if the signal is not caught. .TP +.B K +The process is killed if the signal is not caught. If the signal is received +while ignored or masked, the process is killed even if a handler is defined to +catch the signal. +.TP .B c The signal causes a core dump. .TP diff --git a/servers/pm/glo.h b/servers/pm/glo.h index 9bafc6533..4485e9710 100644 --- a/servers/pm/glo.h +++ b/servers/pm/glo.h @@ -21,6 +21,7 @@ EXTERN int call_nr; /* system call number */ extern _PROTOTYPE (int (*call_vec[]), (void) ); /* system call handlers */ EXTERN sigset_t core_sset; /* which signals cause core images */ EXTERN sigset_t ign_sset; /* which signals are by default ignored */ +EXTERN sigset_t noign_sset; /* which signals cannot be ignored */ EXTERN u32_t system_hz; /* System clock frequency. */ EXTERN int abort_flag; diff --git a/servers/pm/main.c b/servers/pm/main.c index ede2edcb2..3a59900b0 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -200,6 +200,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) SIGEMT, SIGFPE, SIGBUS, SIGSEGV }; static char ign_sigs[] = { SIGCHLD, SIGWINCH, SIGCONT }; static char mess_sigs[] = { SIGTERM, SIGHUP, SIGABRT, SIGQUIT }; + static char noign_sigs[] = { SIGILL, SIGTRAP, SIGEMT, SIGFPE, + SIGBUS, SIGSEGV }; register struct mproc *rmp; register char *sig_ptr; message mess; @@ -218,6 +220,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) sigemptyset(&ign_sset); for (sig_ptr = ign_sigs; sig_ptr < ign_sigs+sizeof(ign_sigs); sig_ptr++) sigaddset(&ign_sset, *sig_ptr); + sigemptyset(&noign_sset); + for (sig_ptr = noign_sigs; sig_ptr < noign_sigs+sizeof(noign_sigs); sig_ptr++) + sigaddset(&noign_sset, *sig_ptr); /* Obtain a copy of the boot monitor parameters and the kernel info struct. * Parse the list of free memory chunks. This list is what the boot monitor diff --git a/servers/pm/signal.c b/servers/pm/signal.c index 7a234c050..a13756857 100644 --- a/servers/pm/signal.c +++ b/servers/pm/signal.c @@ -351,7 +351,7 @@ int trace; /* pass signal to tracer first? */ * context from the sigcontext structure. * If there is insufficient stack space, kill the process. */ - int r, slot; + int r, slot, badignore; slot = (int) (rmp - mproc); if ((rmp->mp_flags & (IN_USE | EXITING)) != IN_USE) { @@ -387,16 +387,22 @@ int trace; /* pass signal to tracer first? */ return; } - if (sigismember(&rmp->mp_ignore, signo)) { + /* some signals cannot be safely ignored */ + badignore = sigismember(&noign_sset, signo) && ( + sigismember(&rmp->mp_ignore, signo) || + sigismember(&rmp->mp_sigmask, signo) || + sigismember(&rmp->mp_sig2mess, signo)); + + if (!badignore && sigismember(&rmp->mp_ignore, signo)) { /* Signal should be ignored. */ return; } - if (sigismember(&rmp->mp_sigmask, signo)) { + if (!badignore && sigismember(&rmp->mp_sigmask, signo)) { /* Signal should be blocked. */ sigaddset(&rmp->mp_sigpending, signo); return; } - if (sigismember(&rmp->mp_sig2mess, signo)) { + if (!badignore && sigismember(&rmp->mp_sig2mess, signo)) { /* Mark event pending in process slot and send notification. */ sigaddset(&rmp->mp_sigpending, signo); notify(rmp->mp_endpoint); @@ -412,7 +418,7 @@ int trace; /* pass signal to tracer first? */ return; } - if (sigismember(&rmp->mp_catch, signo)) { + if (!badignore && sigismember(&rmp->mp_catch, signo)) { /* Signal is caught. First interrupt the process's current call, if * applicable. This may involve a roundtrip to FS, in which case we'll * have to check back later. @@ -436,7 +442,7 @@ int trace; /* pass signal to tracer first? */ /* We were unable to spawn a signal handler. Kill the process. */ } - else if (sigismember(&ign_sset, signo)) { + else if (!badignore && sigismember(&ign_sset, signo)) { /* Signal defaults to being ignored. */ return; } diff --git a/test/test5.c b/test/test5.c index 284820813..9593584f6 100644 --- a/test/test5.c +++ b/test/test5.c @@ -279,11 +279,11 @@ void test5g() int n; subtest = 7; - Signal(11, func11); - Signal(11, SIG_IGN); + Signal(SIGUSR1, func11); + Signal(SIGUSR1, SIG_IGN); n = getpid(); - if (kill(n, 11) != 0) e(1); - Signal(11, SIG_DFL); + if (kill(n, SIGUSR1) != 0) e(1); + Signal(SIGUSR1, SIG_DFL); } void funcalrm(s)