From: Oleg Nesterov Date: Wed, 30 Apr 2008 07:53:05 +0000 (-0700) Subject: signals: allow the kernel to actually kill /sbin/init X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=80fe728d593e3a048a56610de932919f7d6d968a;p=openwrt%2Fstaging%2Fblogic.git 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 Cc: Roland McGrath Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- 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) * since we do not want to have a signal handler that was blocked * be invoked when user space had explicitly blocked it. * - * We don't want to have recursive SIGSEGV's etc, for example. + * We don't want to have recursive SIGSEGV's etc, for example, + * that is why we also clear SIGNAL_UNKILLABLE. */ int 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) recalc_sigpending_and_wake(t); } } + if (action->sa.sa_handler == SIG_DFL) + t->signal->flags &= ~SIGNAL_UNKILLABLE; ret = specific_send_sig_info(sig, info, t); spin_unlock_irqrestore(&t->sighand->siglock, flags);