summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2011-07-27 12:49:44 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-27 12:53:36 -0700
commitc1095c6da518b0b64e724f629051fa67655cd8d9 (patch)
tree8c2e33ca6c8e3caa71437c3b69b36a8cf03b4f08
parent678624e401b0b7747762b5223fb23f86dcdacc93 (diff)
downloadlinux-c1095c6da518b0b64e724f629051fa67655cd8d9.tar.gz
linux-c1095c6da518b0b64e724f629051fa67655cd8d9.tar.bz2
linux-c1095c6da518b0b64e724f629051fa67655cd8d9.zip
signals: sys_ssetmask/sys_rt_sigsuspend should use set_current_blocked()
sys_ssetmask(), sys_rt_sigsuspend() and compat_sys_rt_sigsuspend() change ->blocked directly. This is not correct, see the changelog in e6fa16ab "signal: sigprocmask() should do retarget_shared_pending()" Change them to use set_current_blocked(). Another change is that now we are doing ->saved_sigmask = ->blocked lockless, it doesn't make any sense to do this under ->siglock. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Matt Fleming <matt.fleming@linux.intel.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/compat.c5
-rw-r--r--kernel/signal.c17
2 files changed, 6 insertions, 16 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 18197ae2d465..616c78197cca 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -992,11 +992,8 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat
sigset_from_compat(&newset, &newset32);
sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
- spin_lock_irq(&current->sighand->siglock);
current->saved_sigmask = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&newset);
current->state = TASK_INTERRUPTIBLE;
schedule();
diff --git a/kernel/signal.c b/kernel/signal.c
index d7f70aed1cc0..291c9700be75 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3102,15 +3102,11 @@ SYSCALL_DEFINE0(sgetmask)
SYSCALL_DEFINE1(ssetmask, int, newmask)
{
- int old;
-
- spin_lock_irq(&current->sighand->siglock);
- old = current->blocked.sig[0];
+ int old = current->blocked.sig[0];
+ sigset_t newset;
- siginitset(&current->blocked, newmask & ~(sigmask(SIGKILL)|
- sigmask(SIGSTOP)));
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ siginitset(&newset, newmask & ~(sigmask(SIGKILL) | sigmask(SIGSTOP)));
+ set_current_blocked(&newset);
return old;
}
@@ -3167,11 +3163,8 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize)
return -EFAULT;
sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
- spin_lock_irq(&current->sighand->siglock);
current->saved_sigmask = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&newset);
current->state = TASK_INTERRUPTIBLE;
schedule();