Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-block.git] / kernel / signal.c
index aa1fb9f905dbc5d66194218df339c467f04b2f9a..babb36d3d03911df511f55b25e68ff179c6cc9da 100644 (file)
@@ -2599,7 +2599,6 @@ SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, nset,
 COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset,
                compat_sigset_t __user *, oset, compat_size_t, sigsetsize)
 {
-#ifdef __BIG_ENDIAN
        sigset_t old_set = current->blocked;
 
        /* XXX: Don't preclude handling different sized sigset_t's.  */
@@ -2607,38 +2606,22 @@ COMPAT_SYSCALL_DEFINE4(rt_sigprocmask, int, how, compat_sigset_t __user *, nset,
                return -EINVAL;
 
        if (nset) {
-               compat_sigset_t new32;
                sigset_t new_set;
                int error;
-               if (copy_from_user(&new32, nset, sizeof(compat_sigset_t)))
+               if (get_compat_sigset(&new_set, nset))
                        return -EFAULT;
-
-               sigset_from_compat(&new_set, &new32);
                sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP));
 
                error = sigprocmask(how, &new_set, NULL);
                if (error)
                        return error;
        }
-       if (oset) {
-               compat_sigset_t old32;
-               sigset_to_compat(&old32, &old_set);
-               if (copy_to_user(oset, &old32, sizeof(compat_sigset_t)))
-                       return -EFAULT;
-       }
-       return 0;
-#else
-       return sys_rt_sigprocmask(how, (sigset_t __user *)nset,
-                                 (sigset_t __user *)oset, sigsetsize);
-#endif
+       return oset ? put_compat_sigset(oset, &old_set, sizeof(*oset)) : 0;
 }
 #endif
 
-static int do_sigpending(void *set, unsigned long sigsetsize)
+static int do_sigpending(sigset_t *set)
 {
-       if (sigsetsize > sizeof(sigset_t))
-               return -EINVAL;
-
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(set, &current->pending.signal,
                  &current->signal->shared_pending.signal);
@@ -2658,7 +2641,12 @@ static int do_sigpending(void *set, unsigned long sigsetsize)
 SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
 {
        sigset_t set;
-       int err = do_sigpending(&set, sigsetsize);
+       int err;
+
+       if (sigsetsize > sizeof(*uset))
+               return -EINVAL;
+
+       err = do_sigpending(&set);
        if (!err && copy_to_user(uset, &set, sigsetsize))
                err = -EFAULT;
        return err;
@@ -2668,20 +2656,16 @@ SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
 COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset,
                compat_size_t, 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;
-       }
+       int err;
+
+       if (sigsetsize > sizeof(*uset))
+               return -EINVAL;
+
+       err = do_sigpending(&set);
+       if (!err)
+               err = put_compat_sigset(uset, &set, sigsetsize);
        return err;
-#else
-       return sys_rt_sigpending((sigset_t __user *)uset, sigsetsize);
-#endif
 }
 #endif
 
@@ -2915,7 +2899,6 @@ COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
                struct compat_siginfo __user *, uinfo,
                struct compat_timespec __user *, uts, compat_size_t, sigsetsize)
 {
-       compat_sigset_t s32;
        sigset_t s;
        struct timespec t;
        siginfo_t info;
@@ -2924,9 +2907,8 @@ COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
        if (sigsetsize != sizeof(sigset_t))
                return -EINVAL;
 
-       if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
+       if (get_compat_sigset(&s, uthese))
                return -EFAULT;
-       sigset_from_compat(&s, &s32);
 
        if (uts) {
                if (compat_get_timespec(&t, uts))
@@ -3344,15 +3326,11 @@ SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set)
 #ifdef CONFIG_COMPAT
 COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set32)
 {
-#ifdef __BIG_ENDIAN
        sigset_t set;
-       int err = do_sigpending(&set, sizeof(set.sig[0]));
+       int err = do_sigpending(&set);
        if (!err)
                err = put_user(set.sig[0], set32);
        return err;
-#else
-       return sys_rt_sigpending((sigset_t __user *)set32, sizeof(*set32));
-#endif
 }
 #endif
 
@@ -3450,7 +3428,6 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig,
                compat_size_t, sigsetsize)
 {
        struct k_sigaction new_ka, old_ka;
-       compat_sigset_t mask;
 #ifdef __ARCH_HAS_SA_RESTORER
        compat_uptr_t restorer;
 #endif
@@ -3468,19 +3445,18 @@ COMPAT_SYSCALL_DEFINE4(rt_sigaction, int, sig,
                ret |= get_user(restorer, &act->sa_restorer);
                new_ka.sa.sa_restorer = compat_ptr(restorer);
 #endif
-               ret |= copy_from_user(&mask, &act->sa_mask, sizeof(mask));
+               ret |= get_compat_sigset(&new_ka.sa.sa_mask, &act->sa_mask);
                ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
                if (ret)
                        return -EFAULT;
-               sigset_from_compat(&new_ka.sa.sa_mask, &mask);
        }
 
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
        if (!ret && oact) {
-               sigset_to_compat(&mask, &old_ka.sa.sa_mask);
                ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), 
                               &oact->sa_handler);
-               ret |= copy_to_user(&oact->sa_mask, &mask, sizeof(mask));
+               ret |= put_compat_sigset(&oact->sa_mask, &old_ka.sa.sa_mask,
+                                        sizeof(oact->sa_mask));
                ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 #ifdef __ARCH_HAS_SA_RESTORER
                ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer),
@@ -3660,22 +3636,15 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize)
 #ifdef CONFIG_COMPAT
 COMPAT_SYSCALL_DEFINE2(rt_sigsuspend, compat_sigset_t __user *, unewset, compat_size_t, sigsetsize)
 {
-#ifdef __BIG_ENDIAN
        sigset_t newset;
-       compat_sigset_t newset32;
 
        /* XXX: Don't preclude handling different sized sigset_t's.  */
        if (sigsetsize != sizeof(sigset_t))
                return -EINVAL;
 
-       if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
+       if (get_compat_sigset(&newset, unewset))
                return -EFAULT;
-       sigset_from_compat(&newset, &newset32);
        return sigsuspend(&newset);
-#else
-       /* on little-endian bitmaps don't care about granularity */
-       return sys_rt_sigsuspend((sigset_t __user *)unewset, sigsetsize);
-#endif
 }
 #endif