aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2008-04-30 03:53:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:37 -0400
commit80fe728d593e3a048a56610de932919f7d6d968a (patch)
treeff8effec1d05d871bcbb1347947d2a0970a8ff32 /kernel/signal.c
parent7a5e873f096e04e6d8719e4ecb7b70d2decca503 (diff)
signals: allow the kernel to actually kill /sbin/init
Currently the buggy /sbin/init hangs if SIGSEGV/etc happens. The kernel sends the signal, init dequeues it and ignores, returns from the exception, repeats the faulting instruction, and so on forever. Imho, such a behaviour is not good. I think that the explicit loud death of the buggy /sbin/init is better than the silent hang. Change force_sig_info() to clear SIGNAL_UNKILLABLE when the task should be really killed. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 646a8765696a..9ac737e53df1 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -892,7 +892,8 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
892 * since we do not want to have a signal handler that was blocked 892 * since we do not want to have a signal handler that was blocked
893 * be invoked when user space had explicitly blocked it. 893 * be invoked when user space had explicitly blocked it.
894 * 894 *
895 * We don't want to have recursive SIGSEGV's etc, for example. 895 * We don't want to have recursive SIGSEGV's etc, for example,
896 * that is why we also clear SIGNAL_UNKILLABLE.
896 */ 897 */
897int 898int
898force_sig_info(int sig, struct siginfo *info, struct task_struct *t) 899force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
@@ -912,6 +913,8 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
912 recalc_sigpending_and_wake(t); 913 recalc_sigpending_and_wake(t);
913 } 914 }
914 } 915 }
916 if (action->sa.sa_handler == SIG_DFL)
917 t->signal->flags &= ~SIGNAL_UNKILLABLE;
915 ret = specific_send_sig_info(sig, info, t); 918 ret = specific_send_sig_info(sig, info, t);
916 spin_unlock_irqrestore(&t->sighand->siglock, flags); 919 spin_unlock_irqrestore(&t->sighand->siglock, flags);
917 920