diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2008-04-30 03:53:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:37 -0400 |
commit | 80fe728d593e3a048a56610de932919f7d6d968a (patch) | |
tree | ff8effec1d05d871bcbb1347947d2a0970a8ff32 /kernel/signal.c | |
parent | 7a5e873f096e04e6d8719e4ecb7b70d2decca503 (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.c | 5 |
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 | */ |
897 | int | 898 | int |
898 | force_sig_info(int sig, struct siginfo *info, struct task_struct *t) | 899 | force_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 | ||