Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Jul 2017 03:57:13 +0000 (20:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Jul 2017 03:57:13 +0000 (20:57 -0700)
Pull misc compat stuff updates from Al Viro:
 "This part is basically untangling various compat stuff. Compat
  syscalls moved to their native counterparts, getting rid of quite a
  bit of double-copying and/or set_fs() uses. A lot of field-by-field
  copyin/copyout killed off.

   - kernel/compat.c is much closer to containing just the
     copyin/copyout of compat structs. Not all compat syscalls are gone
     from it yet, but it's getting there.

   - ipc/compat_mq.c killed off completely.

   - block/compat_ioctl.c cleaned up; floppy compat ioctls moved to
     drivers/block/floppy.c where they belong. Yes, there are several
     drivers that implement some of the same ioctls. Some are m68k and
     one is 32bit-only pmac. drivers/block/floppy.c is the only one in
     that bunch that can be built on biarch"

* 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  mqueue: move compat syscalls to native ones
  usbdevfs: get rid of field-by-field copyin
  compat_hdio_ioctl: get rid of set_fs()
  take floppy compat ioctls to sodding floppy.c
  ipmi: get rid of field-by-field __get_user()
  ipmi: get COMPAT_IPMICTL_RECEIVE_MSG in sync with the native one
  rt_sigtimedwait(): move compat to native
  select: switch compat_{get,put}_fd_set() to compat_{get,put}_bitmap()
  put_compat_rusage(): switch to copy_to_user()
  sigpending(): move compat to native
  getrlimit()/setrlimit(): move compat to native
  times(2): move compat to native
  compat_{get,put}_bitmap(): use unsafe_{get,put}_user()
  fb_get_fscreeninfo(): don't bother with do_fb_ioctl()
  do_sigaltstack(): lift copying to/from userland into callers
  take compat_sys_old_getrlimit() to native syscall
  trim __ARCH_WANT_SYS_OLD_GETRLIMIT

1  2 
drivers/block/floppy.c
drivers/usb/core/devio.c
fs/select.c
include/linux/compat.h
include/linux/signal.h
include/linux/time.h
kernel/compat.c
kernel/signal.c
kernel/sys.c

Simple merge
Simple merge
diff --cc fs/select.c
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc kernel/compat.c
index 0621c8e1ab7273fb33eee4812c58bf4c9b07f2d6,36e6e7c405e34430512ed79ea4d55a56a0b55b8a..6f0a0e723a0622a8876f9bfc81bbe08346db2ffd
@@@ -223,77 -213,143 +223,30 @@@ int compat_convert_timespec(struct time
        return 0;
  }
  
 -static long compat_nanosleep_restart(struct restart_block *restart)
 +int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i)
  {
 -      struct compat_timespec __user *rmtp;
 -      struct timespec rmt;
 -      mm_segment_t oldfs;
 -      long ret;
 +      struct compat_itimerval v32;
  
 -      restart->nanosleep.rmtp = (struct timespec __user *) &rmt;
 -      oldfs = get_fs();
 -      set_fs(KERNEL_DS);
 -      ret = hrtimer_nanosleep_restart(restart);
 -      set_fs(oldfs);
 -
 -      if (ret == -ERESTART_RESTARTBLOCK) {
 -              rmtp = restart->nanosleep.compat_rmtp;
 -
 -              if (rmtp && compat_put_timespec(&rmt, rmtp))
 -                      return -EFAULT;
 -      }
 -
 -      return ret;
 -}
 -
 -COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
 -                     struct compat_timespec __user *, rmtp)
 -{
 -      struct timespec tu, rmt;
 -      struct timespec64 tu64;
 -      mm_segment_t oldfs;
 -      long ret;
 -
 -      if (compat_get_timespec(&tu, rqtp))
 +      if (copy_from_user(&v32, i, sizeof(struct compat_itimerval)))
                return -EFAULT;
 -
 -      tu64 = timespec_to_timespec64(tu);
 -      if (!timespec64_valid(&tu64))
 -              return -EINVAL;
 -
 -      oldfs = get_fs();
 -      set_fs(KERNEL_DS);
 -      ret = hrtimer_nanosleep(&tu64,
 -                              rmtp ? (struct timespec __user *)&rmt : NULL,
 -                              HRTIMER_MODE_REL, CLOCK_MONOTONIC);
 -      set_fs(oldfs);
 -
 -      /*
 -       * hrtimer_nanosleep() can only return 0 or
 -       * -ERESTART_RESTARTBLOCK here because:
 -       *
 -       * - we call it with HRTIMER_MODE_REL and therefor exclude the
 -       *   -ERESTARTNOHAND return path.
 -       *
 -       * - we supply the rmtp argument from the task stack (due to
 -       *   the necessary compat conversion. So the update cannot
 -       *   fail, which excludes the -EFAULT return path as well. If
 -       *   it fails nevertheless we have a bigger problem and wont
 -       *   reach this place anymore.
 -       *
 -       * - if the return value is 0, we do not have to update rmtp
 -       *    because there is no remaining time.
 -       *
 -       * We check for -ERESTART_RESTARTBLOCK nevertheless if the
 -       * core implementation decides to return random nonsense.
 -       */
 -      if (ret == -ERESTART_RESTARTBLOCK) {
 -              struct restart_block *restart = &current->restart_block;
 -
 -              restart->fn = compat_nanosleep_restart;
 -              restart->nanosleep.compat_rmtp = rmtp;
 -
 -              if (rmtp && compat_put_timespec(&rmt, rmtp))
 -                      return -EFAULT;
 -      }
 -      return ret;
 -}
 -
 -static inline long get_compat_itimerval(struct itimerval *o,
 -              struct compat_itimerval __user *i)
 -{
 -      return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
 -              (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
 -               __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
 -               __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
 -               __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
 -}
 -
 -static inline long put_compat_itimerval(struct compat_itimerval __user *o,
 -              struct itimerval *i)
 -{
 -      return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
 -              (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
 -               __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
 -               __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
 -               __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
 -}
 -
 -asmlinkage long sys_ni_posix_timers(void);
 -
 -COMPAT_SYSCALL_DEFINE2(getitimer, int, which,
 -              struct compat_itimerval __user *, it)
 -{
 -      struct itimerval kit;
 -      int error;
 -
 -      if (!IS_ENABLED(CONFIG_POSIX_TIMERS))
 -              return sys_ni_posix_timers();
 -
 -      error = do_getitimer(which, &kit);
 -      if (!error && put_compat_itimerval(it, &kit))
 -              error = -EFAULT;
 -      return error;
 +      o->it_interval.tv_sec = v32.it_interval.tv_sec;
 +      o->it_interval.tv_usec = v32.it_interval.tv_usec;
 +      o->it_value.tv_sec = v32.it_value.tv_sec;
 +      o->it_value.tv_usec = v32.it_value.tv_usec;
 +      return 0;
  }
  
 -COMPAT_SYSCALL_DEFINE3(setitimer, int, which,
 -              struct compat_itimerval __user *, in,
 -              struct compat_itimerval __user *, out)
 +int put_compat_itimerval(struct compat_itimerval __user *o, const struct itimerval *i)
  {
 -      struct itimerval kin, kout;
 -      int error;
 -
 -      if (!IS_ENABLED(CONFIG_POSIX_TIMERS))
 -              return sys_ni_posix_timers();
 +      struct compat_itimerval v32;
  
 -      if (in) {
 -              if (get_compat_itimerval(&kin, in))
 -                      return -EFAULT;
 -      } else
 -              memset(&kin, 0, sizeof(kin));
 -
 -      error = do_setitimer(which, &kin, out ? &kout : NULL);
 -      if (error || !out)
 -              return error;
 -      if (put_compat_itimerval(out, &kout))
 -              return -EFAULT;
 -      return 0;
 +      v32.it_interval.tv_sec = i->it_interval.tv_sec;
 +      v32.it_interval.tv_usec = i->it_interval.tv_usec;
 +      v32.it_value.tv_sec = i->it_value.tv_sec;
 +      v32.it_value.tv_usec = i->it_value.tv_usec;
 +      return copy_to_user(o, &v32, sizeof(struct compat_itimerval)) ? -EFAULT : 0;
  }
  
- static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
- {
-       return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
- }
- COMPAT_SYSCALL_DEFINE1(times, struct compat_tms __user *, tbuf)
- {
-       if (tbuf) {
-               struct tms tms;
-               struct compat_tms tmp;
-               do_sys_times(&tms);
-               /* Convert our struct tms to the compat version. */
-               tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
-               tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
-               tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
-               tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
-               if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
-                       return -EFAULT;
-       }
-       force_successful_syscall_return();
-       return compat_jiffies_to_clock_t(jiffies);
- }
- #ifdef __ARCH_WANT_SYS_SIGPENDING
- /*
-  * Assumption: old_sigset_t and compat_old_sigset_t are both
-  * types that can be passed to put_user()/get_user().
-  */
- COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set)
- {
-       old_sigset_t s;
-       long ret;
-       mm_segment_t old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_sigpending((old_sigset_t __user *) &s);
-       set_fs(old_fs);
-       if (ret == 0)
-               ret = put_user(s, set);
-       return ret;
- }
- #endif
  #ifdef __ARCH_WANT_SYS_SIGPROCMASK
  
  /*
@@@ -668,38 -866,64 +531,6 @@@ sigset_to_compat(compat_sigset_t *compa
        }
  }
  
- 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;
-       long ret;
 -#ifdef __ARCH_WANT_COMPAT_SYS_TIME
--
-       if (sigsetsize != sizeof(sigset_t))
-               return -EINVAL;
 -/* compat_time_t is a 32 bit "long" and needs to get converted. */
--
-       if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
-               return -EFAULT;
-       sigset_from_compat(&s, &s32);
 -COMPAT_SYSCALL_DEFINE1(time, compat_time_t __user *, tloc)
 -{
 -      compat_time_t i;
 -      struct timeval tv;
--
-       if (uts) {
-               if (compat_get_timespec(&t, uts))
 -      do_gettimeofday(&tv);
 -      i = tv.tv_sec;
 -
 -      if (tloc) {
 -              if (put_user(i,tloc))
--                      return -EFAULT;
--      }
 -      force_successful_syscall_return();
 -      return i;
 -}
--
-       ret = do_sigtimedwait(&s, &info, uts ? &t : NULL);
 -COMPAT_SYSCALL_DEFINE1(stime, compat_time_t __user *, tptr)
 -{
 -      struct timespec tv;
 -      int err;
--
-       if (ret > 0 && uinfo) {
-               if (copy_siginfo_to_user32(uinfo, &info))
-                       ret = -EFAULT;
-       }
 -      if (get_user(tv.tv_sec, tptr))
 -              return -EFAULT;
 -
 -      tv.tv_nsec = 0;
 -
 -      err = security_settime(&tv, NULL);
 -      if (err)
 -              return err;
 -
 -      do_settimeofday(&tv);
 -      return 0;
 -}
 -
 -#endif /* __ARCH_WANT_COMPAT_SYS_TIME */
 -
 -COMPAT_SYSCALL_DEFINE1(adjtimex, struct compat_timex __user *, utp)
 -{
 -      struct timex txc;
 -      int err, ret;
 -
 -      err = compat_get_timex(&txc, utp);
 -      if (err)
 -              return err;
 -
 -      ret = do_adjtimex(&txc);
 -
 -      err = compat_put_timex(utp, &txc);
 -      if (err)
 -              return err;
--
--      return ret;
--}
--
  #ifdef CONFIG_NUMA
  COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages,
                       compat_uptr_t __user *, pages32,
diff --cc kernel/signal.c
Simple merge
diff --cc kernel/sys.c
Simple merge