diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/signal.c | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 8aa3a2e226af..bb9200070ea0 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -2364,40 +2364,34 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset) | |||
2364 | * @oset: previous value of signal mask if non-null | 2364 | * @oset: previous value of signal mask if non-null |
2365 | * @sigsetsize: size of sigset_t type | 2365 | * @sigsetsize: size of sigset_t type |
2366 | */ | 2366 | */ |
2367 | SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, set, | 2367 | SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, nset, |
2368 | sigset_t __user *, oset, size_t, sigsetsize) | 2368 | sigset_t __user *, oset, size_t, sigsetsize) |
2369 | { | 2369 | { |
2370 | int error = -EINVAL; | ||
2371 | sigset_t old_set, new_set; | 2370 | sigset_t old_set, new_set; |
2371 | int error; | ||
2372 | 2372 | ||
2373 | /* XXX: Don't preclude handling different sized sigset_t's. */ | 2373 | /* XXX: Don't preclude handling different sized sigset_t's. */ |
2374 | if (sigsetsize != sizeof(sigset_t)) | 2374 | if (sigsetsize != sizeof(sigset_t)) |
2375 | goto out; | 2375 | return -EINVAL; |
2376 | 2376 | ||
2377 | if (set) { | 2377 | old_set = current->blocked; |
2378 | error = -EFAULT; | 2378 | |
2379 | if (copy_from_user(&new_set, set, sizeof(*set))) | 2379 | if (nset) { |
2380 | goto out; | 2380 | if (copy_from_user(&new_set, nset, sizeof(sigset_t))) |
2381 | return -EFAULT; | ||
2381 | sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP)); | 2382 | sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP)); |
2382 | 2383 | ||
2383 | error = sigprocmask(how, &new_set, &old_set); | 2384 | error = sigprocmask(how, &new_set, NULL); |
2384 | if (error) | 2385 | if (error) |
2385 | goto out; | 2386 | return error; |
2386 | if (oset) | 2387 | } |
2387 | goto set_old; | ||
2388 | } else if (oset) { | ||
2389 | spin_lock_irq(¤t->sighand->siglock); | ||
2390 | old_set = current->blocked; | ||
2391 | spin_unlock_irq(¤t->sighand->siglock); | ||
2392 | 2388 | ||
2393 | set_old: | 2389 | if (oset) { |
2394 | error = -EFAULT; | 2390 | if (copy_to_user(oset, &old_set, sizeof(sigset_t))) |
2395 | if (copy_to_user(oset, &old_set, sizeof(*oset))) | 2391 | return -EFAULT; |
2396 | goto out; | ||
2397 | } | 2392 | } |
2398 | error = 0; | 2393 | |
2399 | out: | 2394 | return 0; |
2400 | return error; | ||
2401 | } | 2395 | } |
2402 | 2396 | ||
2403 | long do_sigpending(void __user *set, unsigned long sigsetsize) | 2397 | long do_sigpending(void __user *set, unsigned long sigsetsize) |