Signed-off-by: Arnd Bergmann <[email protected]>
---
 fs/compat.c | 47 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/fs/compat.c b/fs/compat.c
index b9e55d5de311..fac162df4b9b 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1125,6 +1125,7 @@ sticky:
        return ret;
 }
 
+#ifdef CONFIG_COMPAT
 /*
  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
  * 64-bit unsigned longs.
@@ -1187,7 +1188,10 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t 
__user *ufdset,
                return -EFAULT;
        return 0;
 }
-
+#else
+#define compat_get_fd_set get_fd_set
+#define compat_set_fd_set set_fd_set
+#endif
 
 /*
  * This is a virtual copy of sys_select from fs/select.c and probably
@@ -1316,12 +1320,32 @@ COMPAT_SYSCALL_DEFINE1(old_select, struct 
compat_sel_arg_struct __user *, arg)
                                 compat_ptr(a.exp), compat_ptr(a.tvp));
 }
 
+int compat_copy_sigset_from_user(sigset_t *out, const compat_sigset_t __user 
*in,
+                                size_t sigsetsize)
+{
+#ifdef CONFIG_COMPAT
+       compat_sigset_t ss32;
+
+       if (!in)
+               return 0;
+
+       if (sigsetsize != sizeof(compat_sigset_t))
+               return -EINVAL;
+       if (copy_from_user(&ss32, in, sizeof(ss32)))
+               return -EFAULT;
+       sigset_from_compat(out, &ss32);
+#else
+       if (copy_from_user(out, in, sizeof(*out)))
+               return -EFAULT;
+#endif
+       return 0;
+}
+
 static long do_compat_pselect(int n, compat_ulong_t __user *inp,
        compat_ulong_t __user *outp, compat_ulong_t __user *exp,
        struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask,
        compat_size_t sigsetsize)
 {
-       compat_sigset_t ss32;
        sigset_t ksigmask, sigsaved;
        struct compat_timespec ts;
        struct timespec64 end_time, *to = NULL;
@@ -1337,12 +1361,9 @@ static long do_compat_pselect(int n, compat_ulong_t 
__user *inp,
        }
 
        if (sigmask) {
-               if (sigsetsize != sizeof(compat_sigset_t))
-                       return -EINVAL;
-               if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
-                       return -EFAULT;
-               sigset_from_compat(&ksigmask, &ss32);
-
+               ret = compat_copy_sigset_from_user(&ksigmask, sigmask, 
sigsetsize);
+               if (ret)
+                       return ret;
                sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
                sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
        }
@@ -1390,7 +1411,6 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, 
ufds,
        unsigned int,  nfds, struct compat_timespec __user *, tsp,
        const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
 {
-       compat_sigset_t ss32;
        sigset_t ksigmask, sigsaved;
        struct compat_timespec ts;
        struct timespec64 end_time, *to = NULL;
@@ -1406,12 +1426,9 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, 
ufds,
        }
 
        if (sigmask) {
-               if (sigsetsize != sizeof(compat_sigset_t))
-                       return -EINVAL;
-               if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
-                       return -EFAULT;
-               sigset_from_compat(&ksigmask, &ss32);
-
+               ret = compat_copy_sigset_from_user(&ksigmask, sigmask, 
sigsetsize);
+               if (ret)
+                       return ret;
                sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
                sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
        }
-- 
2.1.0.rc2

_______________________________________________
Y2038 mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/y2038

Reply via email to