From 6b065fe4beefe9ff6e58407707215ab5472b5af9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 2 Aug 2006 20:17:49 -0700 Subject: [PATCH] --- yaml --- r: 33041 b: refs/heads/master c: ae74c3b69a08e1de20cb681ec959f3a48af0006a h: refs/heads/master i: 33039: a3282fba0b8b8f9a4f5181031eb72c0e20474d4c v: v3 --- [refs] | 2 +- trunk/kernel/signal.c | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index d495ebbbd8ae..47912b8adff1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 202668ecb6cb221460d884598dd4cd2e1f3292f3 +refs/heads/master: ae74c3b69a08e1de20cb681ec959f3a48af0006a diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 7fe874d12fae..bfdb5686fa3e 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -791,22 +791,31 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) /* * Force a signal that the process can't ignore: if necessary * we unblock the signal and change any SIG_IGN to SIG_DFL. + * + * Note: If we unblock the signal, we always reset it to SIG_DFL, + * 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. */ - int force_sig_info(int sig, struct siginfo *info, struct task_struct *t) { unsigned long int flags; - int ret; + int ret, blocked, ignored; + struct k_sigaction *action; spin_lock_irqsave(&t->sighand->siglock, flags); - if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) { - t->sighand->action[sig-1].sa.sa_handler = SIG_DFL; - } - if (sigismember(&t->blocked, sig)) { - sigdelset(&t->blocked, sig); + action = &t->sighand->action[sig-1]; + ignored = action->sa.sa_handler == SIG_IGN; + blocked = sigismember(&t->blocked, sig); + if (blocked || ignored) { + action->sa.sa_handler = SIG_DFL; + if (blocked) { + sigdelset(&t->blocked, sig); + recalc_sigpending_tsk(t); + } } - recalc_sigpending_tsk(t); ret = specific_send_sig_info(sig, info, t); spin_unlock_irqrestore(&t->sighand->siglock, flags);