Commit fe9c1db2 authored by Al Viro's avatar Al Viro

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 322a56cb
...@@ -362,6 +362,9 @@ config GENERIC_SIGALTSTACK ...@@ -362,6 +362,9 @@ config GENERIC_SIGALTSTACK
config GENERIC_COMPAT_RT_SIGPROCMASK config GENERIC_COMPAT_RT_SIGPROCMASK
bool bool
config GENERIC_COMPAT_RT_SIGPENDING
bool
# #
# ABI hall of shame # ABI hall of shame
# #
......
...@@ -598,6 +598,10 @@ asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set, ...@@ -598,6 +598,10 @@ asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
compat_sigset_t __user *oset, compat_sigset_t __user *oset,
compat_size_t sigsetsize); compat_size_t sigsetsize);
#endif #endif
#ifdef CONFIG_GENERIC_COMPAT_RT_SIGPENDING
asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset,
compat_size_t sigsetsize);
#endif
asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info); asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg); unsigned long arg);
......
...@@ -243,7 +243,6 @@ extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct ...@@ -243,7 +243,6 @@ extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct
extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
siginfo_t *info); siginfo_t *info);
extern long do_sigpending(void __user *, unsigned long);
extern int do_sigtimedwait(const sigset_t *, siginfo_t *, extern int do_sigtimedwait(const sigset_t *, siginfo_t *,
const struct timespec *); const struct timespec *);
extern int sigprocmask(int, sigset_t *, sigset_t *); extern int sigprocmask(int, sigset_t *, sigset_t *);
......
...@@ -2654,28 +2654,19 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset, ...@@ -2654,28 +2654,19 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset,
#endif #endif
#endif #endif
long do_sigpending(void __user *set, unsigned long sigsetsize) static int do_sigpending(void *set, unsigned long sigsetsize)
{ {
long error = -EINVAL;
sigset_t pending;
if (sigsetsize > sizeof(sigset_t)) if (sigsetsize > sizeof(sigset_t))
goto out; return -EINVAL;
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
sigorsets(&pending, &current->pending.signal, sigorsets(set, &current->pending.signal,
&current->signal->shared_pending.signal); &current->signal->shared_pending.signal);
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
/* Outside the lock because only this thread touches it. */ /* Outside the lock because only this thread touches it. */
sigandsets(&pending, &current->blocked, &pending); sigandsets(set, &current->blocked, set);
return 0;
error = -EFAULT;
if (!copy_to_user(set, &pending, sigsetsize))
error = 0;
out:
return error;
} }
/** /**
...@@ -2684,10 +2675,37 @@ long do_sigpending(void __user *set, unsigned long sigsetsize) ...@@ -2684,10 +2675,37 @@ long do_sigpending(void __user *set, unsigned long sigsetsize)
* @set: stores pending signals * @set: stores pending signals
* @sigsetsize: size of sigset_t type or larger * @sigsetsize: size of sigset_t type or larger
*/ */
SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize) SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
{
sigset_t set;
int err = do_sigpending(&set, sigsetsize);
if (!err && copy_to_user(uset, &set, sigsetsize))
err = -EFAULT;
return err;
}
#ifdef CONFIG_COMPAT
#ifdef CONFIG_GENERIC_COMPAT_RT_SIGPENDING
COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
compat_size_t, sigsetsize)
{ {
return do_sigpending(set, sigsetsize); #ifdef __BIG_ENDIAN
sigset_t set;
int err = do_sigpending(&set, sigsetsize);
if (!err) {
compat_sigset_t set32;
sigset_to_compat(&set32, &set);
/* we can get here only if sigsetsize <= sizeof(set) */
if (copy_to_user(uset, &set32, sigsetsize))
err = -EFAULT;
}
return err;
#else
return sys_rt_sigpending((sigset_t __user *)uset, sigsetsize);
#endif
} }
#endif
#endif
#ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER #ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER
...@@ -3216,7 +3234,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp) ...@@ -3216,7 +3234,7 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
*/ */
SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set)
{ {
return do_sigpending(set, sizeof(*set)); return sys_rt_sigpending((sigset_t __user *)set, sizeof(old_sigset_t));
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment