On Linux/MIPS, a simple test program can create unkillable process. The "sigkill priority fix" was introduced in 2.6.12, but it does not effective for signals sent by force_sig() in kernel. For detailed behavior and testcase, please look at this thread in linux-mips ML:
http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20050907.014234.108739386.anemo%40mba.ocn.ne.jp Here is a proposal fix for generic signal handling code. Patch comment: The "sigkill priority fix" does not work as it desired if any signal (< SIGKILL) was queued by force_sig() in kernel. Search SIGKILL in tsk->pending and tsk->signal->shared_pending first, then search another signals. Signed-off-by: Atsushi Nemoto <[EMAIL PROTECTED]> --- linux-2.6.13/kernel/signal.c 2005-08-29 08:41:01.000000000 +0900 +++ linux/kernel/signal.c 2005-09-07 01:33:52.338420760 +0900 @@ -520,19 +520,14 @@ } static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, - siginfo_t *info) + siginfo_t *info, int sig) { - int sig = 0; - - /* SIGKILL must have priority, otherwise it is quite easy - * to create an unkillable process, sending sig < SIGKILL - * to self */ - if (unlikely(sigismember(&pending->signal, SIGKILL))) { - if (!sigismember(mask, SIGKILL)) - sig = SIGKILL; - } - - if (likely(!sig)) + if (sig) { + /* check signal with priority first */ + if (likely(!sigismember(&pending->signal, sig)) || + sigismember(mask, sig)) + sig = 0; + } else sig = next_signal(pending, mask); if (sig) { if (current->notifier) { @@ -561,10 +556,18 @@ */ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) { - int signr = __dequeue_signal(&tsk->pending, mask, info); + /* SIGKILL must have priority, otherwise it is quite easy + * to create an unkillable process, sending sig < SIGKILL + * to self */ + int signr = __dequeue_signal(&tsk->pending, mask, info, SIGKILL); + if (likely(!signr)) + signr = __dequeue_signal(&tsk->signal->shared_pending, + mask, info, SIGKILL); + if (likely(!signr)) + signr = __dequeue_signal(&tsk->pending, mask, info, 0); if (!signr) signr = __dequeue_signal(&tsk->signal->shared_pending, - mask, info); + mask, info, 0); if (signr && unlikely(sig_kernel_stop(signr))) { /* * Set a marker that we have dequeued a stop signal. Our --- Atsushi Nemoto - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/