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

Pull compat and uaccess updates from Al Viro:

 - {get,put}_compat_sigset() series

 - assorted compat ioctl stuff

 - more set_fs() elimination

 - a few more timespec64 conversions

 - several removals of pointless access_ok() in places where it was
   followed only by non-__ variants of primitives

* 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (24 commits)
  coredump: call do_unlinkat directly instead of sys_unlink
  fs: expose do_unlinkat for built-in callers
  ext4: take handling of EXT4_IOC_GROUP_ADD into a helper, get rid of set_fs()
  ipmi: get rid of pointless access_ok()
  pi433: sanitize ioctl
  cxlflash: get rid of pointless access_ok()
  mtdchar: get rid of pointless access_ok()
  r128: switch compat ioctls to drm_ioctl_kernel()
  selection: get rid of field-by-field copyin
  VT_RESIZEX: get rid of field-by-field copyin
  i2c compat ioctls: move to ->compat_ioctl()
  sched_rr_get_interval(): move compat to native, get rid of set_fs()
  mips: switch to {get,put}_compat_sigset()
  sparc: switch to {get,put}_compat_sigset()
  s390: switch to {get,put}_compat_sigset()
  ppc: switch to {get,put}_compat_sigset()
  parisc: switch to {get,put}_compat_sigset()
  get_compat_sigset()
  get rid of {get,put}_compat_itimerspec()
  io_getevents: Use timespec64 to represent timeouts
  ...
This commit is contained in:
Linus Torvalds 2017-11-17 11:54:55 -08:00
commit 93f30c73ec
32 changed files with 508 additions and 821 deletions

View 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