diff options
author | Oleg Nesterov <oleg@redhat.com> | 2011-07-27 15:49:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-27 15:53:36 -0400 |
commit | c1095c6da518b0b64e724f629051fa67655cd8d9 (patch) | |
tree | 8c2e33ca6c8e3caa71437c3b69b36a8cf03b4f08 /kernel/signal.c | |
parent | 678624e401b0b7747762b5223fb23f86dcdacc93 (diff) |
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>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 17 |
1 files changed, 5 insertions, 12 deletions
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) | |||
3102 | 3102 | ||
3103 | SYSCALL_DEFINE1(ssetmask, int, newmask) | 3103 | SYSCALL_DEFINE1(ssetmask, int, newmask) |
3104 | { | 3104 | { |
3105 | int old; | 3105 | int old = current->blocked.sig[0]; |
3106 | 3106 | sigset_t newset; | |
3107 | spin_lock_irq(¤t->sighand->siglock); | ||
3108 | old = current->blocked.sig[0]; | ||
3109 | 3107 | ||
3110 | siginitset(¤t->blocked, newmask & ~(sigmask(SIGKILL)| | 3108 | siginitset(&newset, newmask & ~(sigmask(SIGKILL) | sigmask(SIGSTOP))); |
3111 | sigmask(SIGSTOP))); | 3109 | set_current_blocked(&newset); |
3112 | recalc_sigpending(); | ||
3113 | spin_unlock_irq(¤t->sighand->siglock); | ||
3114 | 3110 | ||
3115 | return old; | 3111 | return old; |
3116 | } | 3112 | } |
@@ -3167,11 +3163,8 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize) | |||
3167 | return -EFAULT; | 3163 | return -EFAULT; |
3168 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | 3164 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); |
3169 | 3165 | ||
3170 | spin_lock_irq(¤t->sighand->siglock); | ||
3171 | current->saved_sigmask = current->blocked; | 3166 | current->saved_sigmask = current->blocked; |
3172 | current->blocked = newset; | 3167 | set_current_blocked(&newset); |
3173 | recalc_sigpending(); | ||
3174 | spin_unlock_irq(¤t->sighand->siglock); | ||
3175 | 3168 | ||
3176 | current->state = TASK_INTERRUPTIBLE; | 3169 | current->state = TASK_INTERRUPTIBLE; |
3177 | schedule(); | 3170 | schedule(); |