Merge branch 'x86-x32-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Apr 2014 19:51:41 +0000 (12:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Apr 2014 19:51:41 +0000 (12:51 -0700)
Pull compat time conversion changes from Peter Anvin:
 "Despite the branch name this is really neither an x86 nor an
  x32-specific patchset, although it the implementation of the
  discussions that followed the x32 security hole a few months ago.

  This removes get/put_compat_timespec/val() and replaces them with
  compat_get/put_timespec/val() which are savvy as to the current status
  of COMPAT_USE_64BIT_TIME.

  It removes several unused and/or incorrect/misleading functions (like
  compat_put_timeval_convert which doesn't in fact do any conversion)
  and also replaces several open-coded implementations what is now
  called compat_convert_timespec() with that function"

* 'x86-x32-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  compat: Fix sparse address space warnings
  compat: Get rid of (get|put)_compat_time(val|spec)

1  2 
fs/compat.c
include/linux/compat.h
ipc/compat.c
ipc/compat_mq.c
kernel/compat.c

diff --cc fs/compat.c
@@@ -504,9 -506,14 +504,9 @@@ COMPAT_SYSCALL_DEFINE5(io_getevents, co
        struct timespec t;
        struct timespec __user *ut = NULL;
  
 -      ret = -EFAULT;
 -      if (unlikely(!access_ok(VERIFY_WRITE, events, 
 -                              nr * sizeof(struct io_event))))
 -              goto out;
        if (timeout) {
-               if (get_compat_timespec(&t, timeout))
+               if (compat_get_timespec(&t, timeout))
 -                      goto out;
 +                      return -EFAULT;
  
                ut = compat_alloc_user_space(sizeof(*ut));
                if (copy_to_user(ut, &t, sizeof(t)) )
Simple merge
diff --cc ipc/compat.c
@@@ -749,18 -749,11 +749,12 @@@ COMPAT_SYSCALL_DEFINE3(shmctl, int, fir
        return err;
  }
  
 -long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
 -              unsigned nsops, const struct compat_timespec __user *timeout)
 +COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
 +                     unsigned, nsops,
 +                     const struct compat_timespec __user *, timeout)
  {
-       struct timespec __user *ts64 = NULL;
-       if (timeout) {
-               struct timespec ts;
-               ts64 = compat_alloc_user_space(sizeof(*ts64));
-               if (get_compat_timespec(&ts, timeout))
-                       return -EFAULT;
-               if (copy_to_user(ts64, &ts, sizeof(ts)))
-                       return -EFAULT;
-       }
+       struct timespec __user *ts64;
+       if (compat_convert_timespec(&ts64, timeout))
+               return -EFAULT;
        return sys_semtimedop(semid, tsems, nsops, ts64);
  }
diff --cc ipc/compat_mq.c
@@@ -64,24 -64,10 +64,10 @@@ COMPAT_SYSCALL_DEFINE4(mq_open, const c
        return sys_mq_open(u_name, oflag, mode, p);
  }
  
- static int compat_prepare_timeout(struct timespec __user **p,
-                                 const struct compat_timespec __user *u)
- {
-       struct timespec ts;
-       if (!u) {
-               *p = NULL;
-               return 0;
-       }
-       *p = compat_alloc_user_space(sizeof(ts));
-       if (get_compat_timespec(&ts, u) || copy_to_user(*p, &ts, sizeof(ts)))
-               return -EFAULT;
-       return 0;
- }
 -asmlinkage long compat_sys_mq_timedsend(mqd_t mqdes,
 -                      const char __user *u_msg_ptr,
 -                      size_t msg_len, unsigned int msg_prio,
 -                      const struct compat_timespec __user *u_abs_timeout)
 +COMPAT_SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes,
 +                     const char __user *, u_msg_ptr,
 +                     compat_size_t, msg_len, unsigned int, msg_prio,
 +                     const struct compat_timespec __user *, u_abs_timeout)
  {
        struct timespec __user *u_ts;
  
                        msg_prio, u_ts);
  }
  
 -asmlinkage ssize_t compat_sys_mq_timedreceive(mqd_t mqdes,
 -                      char __user *u_msg_ptr,
 -                      size_t msg_len, unsigned int __user *u_msg_prio,
 -                      const struct compat_timespec __user *u_abs_timeout)
 +COMPAT_SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes,
 +                     char __user *, u_msg_ptr,
 +                     compat_size_t, msg_len, unsigned int __user *, u_msg_prio,
 +                     const struct compat_timespec __user *, u_abs_timeout)
  {
        struct timespec __user *u_ts;
-       if (compat_prepare_timeout(&u_ts, u_abs_timeout))
+       if (compat_convert_timespec(&u_ts, u_abs_timeout))
                return -EFAULT;
  
        return sys_mq_timedreceive(mqdes, u_msg_ptr, msg_len,
diff --cc kernel/compat.c
@@@ -127,18 -105,21 +105,21 @@@ COMPAT_SYSCALL_DEFINE2(gettimeofday, st
        return 0;
  }
  
 -asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
 -              struct timezone __user *tz)
 +COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv,
 +                     struct timezone __user *, tz)
  {
-       struct timespec kts;
-       struct timezone ktz;
+       struct timeval user_tv;
+       struct timespec new_ts;
+       struct timezone new_tz;
  
        if (tv) {
-               if (compat_get_timeval_convert(&kts, tv))
+               if (compat_get_timeval(&user_tv, tv))
                        return -EFAULT;
+               new_ts.tv_sec = user_tv.tv_sec;
+               new_ts.tv_nsec = user_tv.tv_usec * NSEC_PER_USEC;
        }
        if (tz) {
-               if (copy_from_user(&ktz, tz, sizeof(ktz)))
+               if (copy_from_user(&new_tz, tz, sizeof(*tz)))
                        return -EFAULT;
        }