diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2012-12-25 19:09:45 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-02-03 15:09:23 -0500 |
| commit | 495dfbf767553980dbd40a19a96a8ca5fa1be616 (patch) | |
| tree | 5c6d499f130f17abad2ee9407272d92e9192879a /kernel/signal.c | |
| parent | 08d32fe504a7670cab3190c624448695adcf70e4 (diff) | |
generic sys_sigaction() and compat_sys_sigaction()
conditional on OLD_SIGACTION/COMPAT_OLD_SIGACTION
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/signal.c')
| -rw-r--r-- | kernel/signal.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index f3665f3de660..79998f5b0f11 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -3409,6 +3409,84 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig, | |||
| 3409 | #endif | 3409 | #endif |
| 3410 | #endif /* !CONFIG_ODD_RT_SIGACTION */ | 3410 | #endif /* !CONFIG_ODD_RT_SIGACTION */ |
| 3411 | 3411 | ||
| 3412 | #ifdef CONFIG_OLD_SIGACTION | ||
| 3413 | SYSCALL_DEFINE3(sigaction, int, sig, | ||
| 3414 | const struct old_sigaction __user *, act, | ||
| 3415 | struct old_sigaction __user *, oact) | ||
| 3416 | { | ||
| 3417 | struct k_sigaction new_ka, old_ka; | ||
| 3418 | int ret; | ||
| 3419 | |||
| 3420 | if (act) { | ||
| 3421 | old_sigset_t mask; | ||
| 3422 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
| 3423 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
| 3424 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || | ||
| 3425 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
| 3426 | __get_user(mask, &act->sa_mask)) | ||
| 3427 | return -EFAULT; | ||
| 3428 | #ifdef __ARCH_HAS_KA_RESTORER | ||
| 3429 | new_ka.ka_restorer = NULL; | ||
| 3430 | #endif | ||
| 3431 | siginitset(&new_ka.sa.sa_mask, mask); | ||
| 3432 | } | ||
| 3433 | |||
| 3434 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
| 3435 | |||
| 3436 | if (!ret && oact) { | ||
| 3437 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
| 3438 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
| 3439 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || | ||
| 3440 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
| 3441 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
| 3442 | return -EFAULT; | ||
| 3443 | } | ||
| 3444 | |||
| 3445 | return ret; | ||
| 3446 | } | ||
| 3447 | #endif | ||
| 3448 | #ifdef CONFIG_COMPAT_OLD_SIGACTION | ||
| 3449 | COMPAT_SYSCALL_DEFINE3(sigaction, int, sig, | ||
| 3450 | const struct compat_old_sigaction __user *, act, | ||
| 3451 | struct compat_old_sigaction __user *, oact) | ||
| 3452 | { | ||
| 3453 | struct k_sigaction new_ka, old_ka; | ||
| 3454 | int ret; | ||
| 3455 | compat_old_sigset_t mask; | ||
| 3456 | compat_uptr_t handler, restorer; | ||
| 3457 | |||
| 3458 | if (act) { | ||
| 3459 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
| 3460 | __get_user(handler, &act->sa_handler) || | ||
| 3461 | __get_user(restorer, &act->sa_restorer) || | ||
| 3462 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
| 3463 | __get_user(mask, &act->sa_mask)) | ||
| 3464 | return -EFAULT; | ||
| 3465 | |||
| 3466 | #ifdef __ARCH_HAS_KA_RESTORER | ||
| 3467 | new_ka.ka_restorer = NULL; | ||
| 3468 | #endif | ||
| 3469 | new_ka.sa.sa_handler = compat_ptr(handler); | ||
| 3470 | new_ka.sa.sa_restorer = compat_ptr(restorer); | ||
| 3471 | siginitset(&new_ka.sa.sa_mask, mask); | ||
| 3472 | } | ||
| 3473 | |||
| 3474 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
| 3475 | |||
| 3476 | if (!ret && oact) { | ||
| 3477 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
| 3478 | __put_user(ptr_to_compat(old_ka.sa.sa_handler), | ||
| 3479 | &oact->sa_handler) || | ||
| 3480 | __put_user(ptr_to_compat(old_ka.sa.sa_restorer), | ||
| 3481 | &oact->sa_restorer) || | ||
| 3482 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
| 3483 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
| 3484 | return -EFAULT; | ||
| 3485 | } | ||
| 3486 | return ret; | ||
| 3487 | } | ||
| 3488 | #endif | ||
| 3489 | |||
| 3412 | #ifdef __ARCH_WANT_SYS_SGETMASK | 3490 | #ifdef __ARCH_WANT_SYS_SGETMASK |
| 3413 | 3491 | ||
| 3414 | /* | 3492 | /* |
