diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-12-25 14:31:38 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-02-03 15:09:19 -0500 |
commit | fe9c1db2cfc363cd30ecfe6480481b280abf8c0a (patch) | |
tree | 0382530cd58c72b56b9860d7bc5bab65a356d9a9 | |
parent | 322a56cb1fcbe228eee5cdb8a9c6df9f797d998c (diff) |
generic compat_sys_rt_sigpending()
conditional on GENERIC_COMPAT_RT_SIGPENDING; by the end of that series
it will become the same thing as COMPAT and conditional will die out.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/Kconfig | 3 | ||||
-rw-r--r-- | include/linux/compat.h | 4 | ||||
-rw-r--r-- | include/linux/signal.h | 1 | ||||
-rw-r--r-- | kernel/signal.c | 52 |
4 files changed, 42 insertions, 18 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 374a68adbf1f..18c0383dcc42 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -362,6 +362,9 @@ config GENERIC_SIGALTSTACK | |||
362 | config GENERIC_COMPAT_RT_SIGPROCMASK | 362 | config GENERIC_COMPAT_RT_SIGPROCMASK |
363 | bool | 363 | bool |
364 | 364 | ||
365 | config GENERIC_COMPAT_RT_SIGPENDING | ||
366 | bool | ||
367 | |||
365 | # | 368 | # |
366 | # ABI hall of shame | 369 | # ABI hall of shame |
367 | # | 370 | # |
diff --git a/include/linux/compat.h b/include/linux/compat.h index 9d3c2a98d537..75548a43a1c5 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -598,6 +598,10 @@ asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set, | |||
598 | compat_sigset_t __user *oset, | 598 | compat_sigset_t __user *oset, |
599 | compat_size_t sigsetsize); | 599 | compat_size_t sigsetsize); |
600 | #endif | 600 | #endif |
601 | #ifdef CONFIG_GENERIC_COMPAT_RT_SIGPENDING | ||
602 | asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset, | ||
603 | compat_size_t sigsetsize); | ||
604 | #endif | ||
601 | asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); | 605 | asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); |
602 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | 606 | asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, |
603 | unsigned long arg); | 607 | unsigned long arg); |
diff --git a/include/linux/signal.h b/include/linux/signal.h index 0a89ffc48466..786bd99fde65 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -243,7 +243,6 @@ extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct | |||
243 | extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); | 243 | extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); |
244 | extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, | 244 | extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, |
245 | siginfo_t *info); | 245 | siginfo_t *info); |
246 | extern long do_sigpending(void __user *, unsigned long); | ||
247 | extern int do_sigtimedwait(const sigset_t *, siginfo_t *, | 246 | extern int do_sigtimedwait(const sigset_t *, siginfo_t *, |
248 | const struct timespec *); | 247 | const struct timespec *); |
249 | extern int sigprocmask(int, sigset_t *, sigset_t *); | 248 | extern int sigprocmask(int, sigset_t *, sigset_t *); |
diff --git a/kernel/signal.c b/kernel/signal.c index bce1222b7315..3040c349b0e1 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -2654,28 +2654,19 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset, | |||
2654 | #endif | 2654 | #endif |
2655 | #endif | 2655 | #endif |
2656 | 2656 | ||
2657 | long do_sigpending(void __user *set, unsigned long sigsetsize) | 2657 | static int do_sigpending(void *set, unsigned long sigsetsize) |
2658 | { | 2658 | { |
2659 | long error = -EINVAL; | ||
2660 | sigset_t pending; | ||
2661 | |||
2662 | if (sigsetsize > sizeof(sigset_t)) | 2659 | if (sigsetsize > sizeof(sigset_t)) |
2663 | goto out; | 2660 | return -EINVAL; |
2664 | 2661 | ||
2665 | spin_lock_irq(¤t->sighand->siglock); | 2662 | spin_lock_irq(¤t->sighand->siglock); |
2666 | sigorsets(&pending, ¤t->pending.signal, | 2663 | sigorsets(set, ¤t->pending.signal, |
2667 | ¤t->signal->shared_pending.signal); | 2664 | ¤t->signal->shared_pending.signal); |
2668 | spin_unlock_irq(¤t->sighand->siglock); | 2665 | spin_unlock_irq(¤t->sighand->siglock); |
2669 | 2666 | ||
2670 | /* Outside the lock because only this thread touches it. */ | 2667 | /* Outside the lock because only this thread touches it. */ |
2671 | sigandsets(&pending, ¤t->blocked, &pending); | 2668 | sigandsets(set, ¤t->blocked, set); |
2672 | 2669 | return 0; | |
2673 | error = -EFAULT; | ||
2674 | if (!copy_to_user(set, &pending, sigsetsize)) | ||
2675 | error = 0; | ||
2676 | |||
2677 | out: | ||
2678 | return error; | ||
2679 | } | 2670 | } |
2680 | 2671 | ||
2681 | /** | 2672 | /** |
@@ -2684,10 +2675,37 @@ out: | |||
2684 | * @set: stores pending signals | 2675 | * @set: stores pending signals |
2685 | * @sigsetsize: size of sigset_t type or larger | 2676 | * @sigsetsize: size of sigset_t type or larger |
2686 | */ | 2677 | */ |
2687 | SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize) | 2678 | SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize) |
2679 | { | ||
2680 | sigset_t set; | ||
2681 | int err = do_sigpending(&set, sigsetsize); | ||
2682 | if (!err && copy_to_user(uset, &set, sigsetsize)) | ||
2683 | err = -EFAULT; | ||
2684 | return err; | ||
2685 | } | ||
2686 | |||
2687 | #ifdef CONFIG_COMPAT | ||
2688 | #ifdef CONFIG_GENERIC_COMPAT_RT_SIGPENDING | ||
2689 | COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset, | ||
2690 | compat_size_t, sigsetsize) | ||
2688 | { | 2691 | { |
2689 | return do_sigpending(set, sigsetsize); | 2692 | #ifdef __BIG_ENDIAN |
2693 | sigset_t set; | ||
2694 | int err = do_sigpending(&set, sigsetsize); | ||
2695 | if (!err) { | ||
2696 | compat_sigset_t set32; | ||
2697 | sigset_to_compat(&set32, &set); | ||
2698 | /* we can get here only if sigsetsize <= sizeof(set) */ | ||
2699 | if (copy_to_user(uset, &set32, sigsetsize)) | ||
2700 | err = -EFAULT; | ||
2701 | } | ||
2702 | return err; | ||
2703 | #else | ||
2704 | return sys_rt_sigpending((sigset_t __user *)uset, sigsetsize); | ||
2705 | #endif | ||
2690 | } | 2706 | } |
2707 | #endif | ||
2708 | #endif | ||
2691 | 2709 | ||
2692 | #ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER | 2710 | #ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER |
2693 | 2711 | ||
@@ -3216,7 +3234,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp) | |||
3216 | */ | 3234 | */ |
3217 | SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) | 3235 | SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) |
3218 | { | 3236 | { |
3219 | return do_sigpending(set, sizeof(*set)); | 3237 | return sys_rt_sigpending((sigset_t __user *)set, sizeof(old_sigset_t)); |
3220 | } | 3238 | } |
3221 | 3239 | ||
3222 | #endif | 3240 | #endif |