Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

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
This commit is contained in:
Linus Torvalds
2017-07-06 20:57:13 -07:00
23 changed files with 1020 additions and 1138 deletions

View File

@@ -1161,59 +1161,25 @@ static
int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{
nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
if (ufdset) {
unsigned long odd;
if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t)))
return -EFAULT;
odd = nr & 1UL;
nr &= ~1UL;
while (nr) {
unsigned long h, l;
if (__get_user(l, ufdset) || __get_user(h, ufdset+1))
return -EFAULT;
ufdset += 2;
*fdset++ = h << 32 | l;
nr -= 2;
}
if (odd && __get_user(*fdset, ufdset))
return -EFAULT;
return compat_get_bitmap(fdset, ufdset, nr);
} else {
/* Tricky, must clear full unsigned long in the
* kernel fdset at the end, this makes sure that
* kernel fdset at the end, ALIGN makes sure that
* actually happens.
*/
memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t));
memset(fdset, 0, ALIGN(nr, BITS_PER_LONG));
return 0;
}
return 0;
}
static
int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{
unsigned long odd;
nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
if (!ufdset)
return 0;
odd = nr & 1UL;
nr &= ~1UL;
while (nr) {
unsigned long h, l;
l = *fdset++;
h = l >> 32;
if (__put_user(l, ufdset) || __put_user(h, ufdset+1))
return -EFAULT;
ufdset += 2;
nr -= 2;
}
if (odd && __put_user(*fdset, ufdset))
return -EFAULT;
return 0;
return compat_put_bitmap(ufdset, fdset, nr);
}