aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-12-25 14:31:38 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2013-02-03 15:09:19 -0500
commitfe9c1db2cfc363cd30ecfe6480481b280abf8c0a (patch)
tree0382530cd58c72b56b9860d7bc5bab65a356d9a9
parent322a56cb1fcbe228eee5cdb8a9c6df9f797d998c (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/Kconfig3
-rw-r--r--include/linux/compat.h4
-rw-r--r--include/linux/signal.h1
-rw-r--r--kernel/signal.c52
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
362config GENERIC_COMPAT_RT_SIGPROCMASK 362config GENERIC_COMPAT_RT_SIGPROCMASK
363 bool 363 bool
364 364
365config 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
602asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset,
603 compat_size_t sigsetsize);
604#endif
601asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); 605asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
602asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, 606asmlinkage 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
243extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); 243extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
244extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, 244extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
245 siginfo_t *info); 245 siginfo_t *info);
246extern long do_sigpending(void __user *, unsigned long);
247extern int do_sigtimedwait(const sigset_t *, siginfo_t *, 246extern int do_sigtimedwait(const sigset_t *, siginfo_t *,
248 const struct timespec *); 247 const struct timespec *);
249extern int sigprocmask(int, sigset_t *, sigset_t *); 248extern 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
2657long do_sigpending(void __user *set, unsigned long sigsetsize) 2657static 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(&current->sighand->siglock); 2662 spin_lock_irq(&current->sighand->siglock);
2666 sigorsets(&pending, &current->pending.signal, 2663 sigorsets(set, &current->pending.signal,
2667 &current->signal->shared_pending.signal); 2664 &current->signal->shared_pending.signal);
2668 spin_unlock_irq(&current->sighand->siglock); 2665 spin_unlock_irq(&current->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, &current->blocked, &pending); 2668 sigandsets(set, &current->blocked, set);
2672 2669 return 0;
2673 error = -EFAULT;
2674 if (!copy_to_user(set, &pending, sigsetsize))
2675 error = 0;
2676
2677out:
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 */
2687SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize) 2678SYSCALL_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
2689COMPAT_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 */
3217SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) 3235SYSCALL_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