[PATCH 41/41] exit: Use __set_task_blocked()

Matt Fleming
2011-08-11T13:59:00Z

From: Matt Fleming <matt.fleming@intel.com>

As described in e6fa16ab ("signal: sigprocmask() should do
retarget_shared_pending()") the modification of current->blocked is
incorrect as we need to check whether the signal we're about to block
is pending in the shared queue.

Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
---
kernel/exit.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/kernel/exit.c b/kernel/exit.c
index 2913b35..a47c0f3 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -369,19 +369,22 @@ static void set_special_pids(struct pid *pid)
*/
int allow_signal(int sig)
{
+ sigset_t blocked;
+
if (!valid_signal(sig) || sig < 1)
return -EINVAL;

spin_lock_irq(&current->sighand->siglock);
/* This is only needed for daemonize()'ed kthreads */
- sigdelset(&current->blocked, sig);
+ siginitset(&blocked, current->blocked);
+ sigdelset(&blocked, sig);
/*
* Kernel threads handle their own signals. Let the signal code
* know it'll be handled, so that they don't get converted to
* SIGKILL or just silently dropped.
*/
current->sighand->action[(sig)-1].sa.sa_handler = (void __user *)2;
- recalc_sigpending();
+ __set_task_blocked(current, &blocked);
spin_unlock_irq(&current->sighand->siglock);
return 0;
}
--
1.7.4.4