Merge branch 'misc.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Nov 2017 19:54:55 +0000 (11:54 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Nov 2017 19:54:55 +0000 (11:54 -0800)
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
  ...

32 files changed:
arch/mips/include/asm/compat-signal.h
arch/parisc/kernel/signal.c
arch/parisc/kernel/signal32.c
arch/parisc/kernel/signal32.h
arch/powerpc/kernel/signal_32.c
arch/s390/kernel/compat_signal.c
arch/sparc/kernel/signal32.c
arch/sparc/kernel/sys_sparc32.c
drivers/char/ipmi/bt-bmc.c
drivers/gpu/drm/r128/r128_drv.h
drivers/gpu/drm/r128/r128_ioc32.c
drivers/gpu/drm/r128/r128_state.c
drivers/i2c/i2c-dev.c
drivers/mtd/mtdchar.c
drivers/scsi/cxlflash/main.c
drivers/staging/pi433/pi433_if.c
drivers/tty/vt/selection.c
drivers/tty/vt/vt_ioctl.c
fs/aio.c
fs/compat_ioctl.c
fs/coredump.c
fs/eventpoll.c
fs/ext4/ioctl.c
fs/internal.h
fs/namei.c
fs/select.c
fs/signalfd.c
include/linux/compat.h
kernel/compat.c
kernel/sched/core.c
kernel/signal.c
virt/kvm/kvm_main.c

index e87cd24..c3b7a25 100644 (file)
 static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d,
        const sigset_t *s)
 {
-       int err;
+       BUILD_BUG_ON(sizeof(*d) != sizeof(*s));
+       BUILD_BUG_ON(_NSIG_WORDS != 2);
 
-       BUG_ON(sizeof(*d) != sizeof(*s));
-       BUG_ON(_NSIG_WORDS != 2);
-
-       err  = __put_user(s->sig[0],       &d->sig[0]);
-       err |= __put_user(s->sig[0] >> 32, &d->sig[1]);
-       err |= __put_user(s->sig[1],       &d->sig[2]);
-       err |= __put_user(s->sig[1] >> 32, &d->sig[3]);
-
-       return err;
+       return put_compat_sigset(d, s, sizeof(*d));
 }
 
 static inline int __copy_conv_sigset_from_user(sigset_t *d,
        const compat_sigset_t __user *s)
 {
-       int err;
-       union sigset_u {
-               sigset_t        s;
-               compat_sigset_t c;
-       } *u = (union sigset_u *) d;
-
-       BUG_ON(sizeof(*d) != sizeof(*s));
-       BUG_ON(_NSIG_WORDS != 2);
-
-#ifdef CONFIG_CPU_BIG_ENDIAN
-       err  = __get_user(u->c.sig[1], &s->sig[0]);
-       err |= __get_user(u->c.sig[0], &s->sig[1]);
-       err |= __get_user(u->c.sig[3], &s->sig[2]);
-       err |= __get_user(u->c.sig[2], &s->sig[3]);
-#endif
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-       err  = __get_user(u->c.sig[0], &s->sig[0]);
-       err |= __get_user(u->c.sig[1], &s->sig[1]);
-       err |= __get_user(u->c.sig[2], &s->sig[2]);
-       err |= __get_user(u->c.sig[3], &s->sig[3]);
-#endif
-
-       return err;
+       return get_compat_sigset(d, s);
 }
 
 #endif /* __ASM_COMPAT_SIGNAL_H */
index f2a4038..342073f 100644 (file)
@@ -93,7 +93,6 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
        unsigned long usp = (regs->gr[30] & ~(0x01UL));
        unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
 #ifdef CONFIG_64BIT
-       compat_sigset_t compat_set;
        struct compat_rt_sigframe __user * compat_frame;
        
        if (is_compat_task())
@@ -114,9 +113,8 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
        
        if (is_compat_task()) {
                DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
-               if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
+               if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask))
                        goto give_sigsegv;
-               sigset_32to64(&set,&compat_set);
        } else
 #endif
        {
@@ -238,7 +236,6 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
        int err = 0;
 #ifdef CONFIG_64BIT
        struct compat_rt_sigframe __user * compat_frame;
-       compat_sigset_t compat_set;
 #endif
        
        usp = (regs->gr[30] & ~(0x01UL));
@@ -261,8 +258,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
                err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 
                                        &compat_frame->regs, regs, in_syscall);
-               sigset_64to32(&compat_set,set);
-               err |= __copy_to_user(&compat_frame->uc.uc_sigmask, &compat_set, sizeof(compat_set));
+               err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set,
+                                        sizeof(compat_sigset_t));
        } else
 #endif
        {       
index 9e0cb6a..41afa9c 100644 (file)
 #define DBG(LEVEL, ...)
 #endif
 
-inline void
-sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
-{
-       s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
-}
-
-inline void
-sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
-{
-       s32->sig[0] = s64->sig[0] & 0xffffffffUL;
-       s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
-}
-
 long
 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
                struct pt_regs *regs)
index af51d4c..719e741 100644 (file)
@@ -79,8 +79,6 @@ struct compat_rt_sigframe {
 #define FUNCTIONCALLFRAME32     48
 #define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
 
-void sigset_32to64(sigset_t *s64, compat_sigset_t *s32);
-void sigset_64to32(compat_sigset_t *s32, sigset_t *s64);
 long restore_sigcontext32(struct compat_sigcontext __user *sc, 
                struct compat_regfile __user *rf,
                struct pt_regs *regs);
index 16d1658..9ffd732 100644 (file)
  */
 static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
 {
-       compat_sigset_t cset;
-
-       switch (_NSIG_WORDS) {
-       case 4: cset.sig[6] = set->sig[3] & 0xffffffffull;
-               cset.sig[7] = set->sig[3] >> 32;
-       case 3: cset.sig[4] = set->sig[2] & 0xffffffffull;
-               cset.sig[5] = set->sig[2] >> 32;
-       case 2: cset.sig[2] = set->sig[1] & 0xffffffffull;
-               cset.sig[3] = set->sig[1] >> 32;
-       case 1: cset.sig[0] = set->sig[0] & 0xffffffffull;
-               cset.sig[1] = set->sig[0] >> 32;
-       }
-       return copy_to_user(uset, &cset, sizeof(*uset));
+       return put_compat_sigset(uset, set, sizeof(*uset));
 }
 
 static inline int get_sigset_t(sigset_t *set,
                               const compat_sigset_t __user *uset)
 {
-       compat_sigset_t s32;
-
-       if (copy_from_user(&s32, uset, sizeof(*uset)))
-               return -EFAULT;
-
-       /*
-        * Swap the 2 words of the 64-bit sigset_t (they are stored
-        * in the "wrong" endian in 32-bit user storage).
-        */
-       switch (_NSIG_WORDS) {
-       case 4: set->sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
-       case 3: set->sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
-       case 2: set->sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
-       case 1: set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
-       }
-       return 0;
+       return get_compat_sigset(set, uset);
 }
 
 #define to_user_ptr(p)         ptr_to_compat(p)
index a4a1208..ef24694 100644 (file)
@@ -50,19 +50,6 @@ typedef struct
        struct ucontext32 uc;
 } rt_sigframe32;
 
-static inline void sigset_to_sigset32(unsigned long *set64,
-                                     compat_sigset_word *set32)
-{
-       set32[0] = (compat_sigset_word) set64[0];
-       set32[1] = (compat_sigset_word)(set64[0] >> 32);
-}
-
-static inline void sigset32_to_sigset(compat_sigset_word *set32,
-                                     unsigned long *set64)
-{
-       set64[0] = (unsigned long) set32[0] | ((unsigned long) set32[1] << 32);
-}
-
 int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
 {
        int err;
@@ -294,12 +281,10 @@ COMPAT_SYSCALL_DEFINE0(sigreturn)
 {
        struct pt_regs *regs = task_pt_regs(current);
        sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
-       compat_sigset_t cset;
        sigset_t set;
 
-       if (__copy_from_user(&cset.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
+       if (get_compat_sigset(&set, (compat_sigset_t __user *)frame->sc.oldmask))
                goto badframe;
-       sigset32_to_sigset(cset.sig, set.sig);
        set_current_blocked(&set);
        save_fpu_regs();
        if (restore_sigregs32(regs, &frame->sregs))
@@ -317,12 +302,10 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
 {
        struct pt_regs *regs = task_pt_regs(current);
        rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
-       compat_sigset_t cset;
        sigset_t set;
 
-       if (__copy_from_user(&cset, &frame->uc.uc_sigmask, sizeof(cset)))
+       if (get_compat_sigset(&set, &frame->uc.uc_sigmask))
                goto badframe;
-       sigset32_to_sigset(cset.sig, set.sig);
        set_current_blocked(&set);
        if (compat_restore_altstack(&frame->uc.uc_stack))
                goto badframe;
@@ -372,7 +355,6 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
 {
        int sig = ksig->sig;
        sigframe32 __user *frame;
-       struct sigcontext32 sc;
        unsigned long restorer;
        size_t frame_size;
 
@@ -394,9 +376,10 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
                return -EFAULT;
 
        /* Create struct sigcontext32 on the signal stack */
-       sigset_to_sigset32(set->sig, sc.oldmask);
-       sc.sregs = (__u32)(unsigned long __force) &frame->sregs;
-       if (__copy_to_user(&frame->sc, &sc, sizeof(frame->sc)))
+       if (put_compat_sigset((compat_sigset_t __user *)frame->sc.oldmask,
+                             set, sizeof(compat_sigset_t)))
+               return -EFAULT;
+       if (__put_user(ptr_to_compat(&frame->sc), &frame->sc.sregs))
                return -EFAULT;
 
        /* Store registers needed to create the signal frame */
@@ -455,7 +438,6 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
 static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
                            struct pt_regs *regs)
 {
-       compat_sigset_t cset;
        rt_sigframe32 __user *frame;
        unsigned long restorer;
        size_t frame_size;
@@ -502,12 +484,11 @@ static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
        store_sigregs();
 
        /* Create ucontext on the signal stack. */
-       sigset_to_sigset32(set->sig, cset.sig);
        if (__put_user(uc_flags, &frame->uc.uc_flags) ||
            __put_user(0, &frame->uc.uc_link) ||
            __compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
            save_sigregs32(regs, &frame->uc.uc_mcontext) ||
-           __copy_to_user(&frame->uc.uc_sigmask, &cset, sizeof(cset)) ||
+           put_compat_sigset(&frame->uc.uc_sigmask, set, sizeof(compat_sigset_t)) ||
            save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
                return -EFAULT;
 
index 5c572de..54a6159 100644 (file)
@@ -249,7 +249,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
        compat_uptr_t fpu_save;
        compat_uptr_t rwin_save;
        sigset_t set;
-       compat_sigset_t seta;
        int err, i;
        
        /* Always make any pending restarted system calls return -EINTR */
@@ -312,7 +311,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
        err |= __get_user(fpu_save, &sf->fpu_save);
        if (!err && fpu_save)
                err |= restore_fpu_state(regs, compat_ptr(fpu_save));
-       err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
+       err |= get_compat_sigset(&set, &sf->mask);
        err |= compat_restore_altstack(&sf->stack);
        if (err)
                goto segv;
@@ -323,7 +322,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
                        goto segv;
        }
 
-       set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
        set_current_blocked(&set);
        return;
 segv:
@@ -555,7 +553,6 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
        void __user *tail;
        int sigframe_size;
        u32 psr;
-       compat_sigset_t seta;
 
        /* 1. Make sure everything is clean */
        synchronize_user_stack();
@@ -625,9 +622,7 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
        /* Setup sigaltstack */
        err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
 
-       seta.sig[1] = (oldset->sig[0] >> 32);
-       seta.sig[0] = oldset->sig[0];
-       err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
+       err |= put_compat_sigset(&sf->mask, oldset, sizeof(compat_sigset_t));
 
        if (!wsaved) {
                err |= copy_in_user((u32 __user *)sf,
index b4e1478..6d964bd 100644 (file)
@@ -160,7 +160,6 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
 {
         struct k_sigaction new_ka, old_ka;
         int ret;
-       compat_sigset_t set32;
 
         /* XXX: Don't preclude handling different sized sigset_t's.  */
         if (sigsetsize != sizeof(compat_sigset_t))
@@ -172,8 +171,7 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
                new_ka.ka_restorer = restorer;
                ret = get_user(u_handler, &act->sa_handler);
                new_ka.sa.sa_handler =  compat_ptr(u_handler);
-               ret |= copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t));
-               sigset_from_compat(&new_ka.sa.sa_mask, &set32);
+               ret |= get_compat_sigset(&new_ka.sa.sa_mask, &act->sa_mask);
                ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
                ret |= get_user(u_restorer, &act->sa_restorer);
                new_ka.sa.sa_restorer = compat_ptr(u_restorer);
@@ -184,9 +182,9 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
        if (!ret && oact) {
-               sigset_to_compat(&set32, &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, &set32, sizeof(compat_sigset_t));
+               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);
                ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);
                if (ret)
index 70d434b..c4ef73c 100644 (file)
@@ -204,9 +204,6 @@ static ssize_t bt_bmc_read(struct file *file, char __user *buf,
        ssize_t ret = 0;
        ssize_t nread;
 
-       if (!access_ok(VERIFY_WRITE, buf, count))
-               return -EFAULT;
-
        WARN_ON(*ppos);
 
        if (wait_event_interruptible(bt_bmc->queue,
@@ -277,9 +274,6 @@ static ssize_t bt_bmc_write(struct file *file, const char __user *buf,
        if (count < 5)
                return -EINVAL;
 
-       if (!access_ok(VERIFY_READ, buf, count))
-               return -EFAULT;
-
        WARN_ON(*ppos);
 
        /*
index 09143b8..2de40d2 100644 (file)
@@ -147,6 +147,10 @@ extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file
 extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
 
+extern int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv);
+
 extern void r128_freelist_reset(struct drm_device *dev);
 
 extern int r128_wait_ring(drm_r128_private_t *dev_priv, int n);
index 663f38c..6589f9e 100644 (file)
@@ -63,39 +63,36 @@ static int compat_r128_init(struct file *file, unsigned int cmd,
                            unsigned long arg)
 {
        drm_r128_init32_t init32;
-       drm_r128_init_t __user *init;
+       drm_r128_init_t init;
 
        if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
                return -EFAULT;
 
-       init = compat_alloc_user_space(sizeof(*init));
-       if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
-           || __put_user(init32.func, &init->func)
-           || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
-           || __put_user(init32.is_pci, &init->is_pci)
-           || __put_user(init32.cce_mode, &init->cce_mode)
-           || __put_user(init32.cce_secure, &init->cce_secure)
-           || __put_user(init32.ring_size, &init->ring_size)
-           || __put_user(init32.usec_timeout, &init->usec_timeout)
-           || __put_user(init32.fb_bpp, &init->fb_bpp)
-           || __put_user(init32.front_offset, &init->front_offset)
-           || __put_user(init32.front_pitch, &init->front_pitch)
-           || __put_user(init32.back_offset, &init->back_offset)
-           || __put_user(init32.back_pitch, &init->back_pitch)
-           || __put_user(init32.depth_bpp, &init->depth_bpp)
-           || __put_user(init32.depth_offset, &init->depth_offset)
-           || __put_user(init32.depth_pitch, &init->depth_pitch)
-           || __put_user(init32.span_offset, &init->span_offset)
-           || __put_user(init32.fb_offset, &init->fb_offset)
-           || __put_user(init32.mmio_offset, &init->mmio_offset)
-           || __put_user(init32.ring_offset, &init->ring_offset)
-           || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
-           || __put_user(init32.buffers_offset, &init->buffers_offset)
-           || __put_user(init32.agp_textures_offset,
-                         &init->agp_textures_offset))
-               return -EFAULT;
-
-       return drm_ioctl(file, DRM_IOCTL_R128_INIT, (unsigned long)init);
+       init.func = init32.func;
+       init.sarea_priv_offset = init32.sarea_priv_offset;
+       init.is_pci = init32.is_pci;
+       init.cce_mode = init32.cce_mode;
+       init.cce_secure = init32.cce_secure;
+       init.ring_size = init32.ring_size;
+       init.usec_timeout = init32.usec_timeout;
+       init.fb_bpp = init32.fb_bpp;
+       init.front_offset = init32.front_offset;
+       init.front_pitch = init32.front_pitch;
+       init.back_offset = init32.back_offset;
+       init.back_pitch = init32.back_pitch;
+       init.depth_bpp = init32.depth_bpp;
+       init.depth_offset = init32.depth_offset;
+       init.depth_pitch = init32.depth_pitch;
+       init.span_offset = init32.span_offset;
+       init.fb_offset = init32.fb_offset;
+       init.mmio_offset = init32.mmio_offset;
+       init.ring_offset = init32.ring_offset;
+       init.ring_rptr_offset = init32.ring_rptr_offset;
+       init.buffers_offset = init32.buffers_offset;
+       init.agp_textures_offset = init32.agp_textures_offset;
+
+       return drm_ioctl_kernel(file, r128_cce_init, &init,
+                       DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
 }
 
 typedef struct drm_r128_depth32 {
@@ -111,25 +108,19 @@ static int compat_r128_depth(struct file *file, unsigned int cmd,
                             unsigned long arg)
 {
        drm_r128_depth32_t depth32;
-       drm_r128_depth_t __user *depth;
+       drm_r128_depth_t depth;
 
        if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32)))
                return -EFAULT;
 
-       depth = compat_alloc_user_space(sizeof(*depth));
-       if (!access_ok(VERIFY_WRITE, depth, sizeof(*depth))
-           || __put_user(depth32.func, &depth->func)
-           || __put_user(depth32.n, &depth->n)
-           || __put_user((int __user *)(unsigned long)depth32.x, &depth->x)
-           || __put_user((int __user *)(unsigned long)depth32.y, &depth->y)
-           || __put_user((unsigned int __user *)(unsigned long)depth32.buffer,
-                         &depth->buffer)
-           || __put_user((unsigned char __user *)(unsigned long)depth32.mask,
-                         &depth->mask))
-               return -EFAULT;
-
-       return drm_ioctl(file, DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
+       depth.func = depth32.func;
+       depth.n = depth32.n;
+       depth.x = compat_ptr(depth32.x);
+       depth.y = compat_ptr(depth32.y);
+       depth.buffer = compat_ptr(depth32.buffer);
+       depth.mask = compat_ptr(depth32.mask);
 
+       return drm_ioctl_kernel(file, r128_cce_depth, &depth, DRM_AUTH);
 }
 
 typedef struct drm_r128_stipple32 {
@@ -140,18 +131,14 @@ static int compat_r128_stipple(struct file *file, unsigned int cmd,
                               unsigned long arg)
 {
        drm_r128_stipple32_t stipple32;
-       drm_r128_stipple_t __user *stipple;
+       drm_r128_stipple_t stipple;
 
        if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32)))
                return -EFAULT;
 
-       stipple = compat_alloc_user_space(sizeof(*stipple));
-       if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple))
-           || __put_user((unsigned int __user *)(unsigned long)stipple32.mask,
-                         &stipple->mask))
-               return -EFAULT;
+       stipple.mask = compat_ptr(stipple32.mask);
 
-       return drm_ioctl(file, DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
+       return drm_ioctl_kernel(file, r128_cce_stipple, &stipple, DRM_AUTH);
 }
 
 typedef struct drm_r128_getparam32 {
@@ -163,19 +150,15 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd,
                                unsigned long arg)
 {
        drm_r128_getparam32_t getparam32;
-       drm_r128_getparam_t __user *getparam;
+       drm_r128_getparam_t getparam;
 
        if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
                return -EFAULT;
 
-       getparam = compat_alloc_user_space(sizeof(*getparam));
-       if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
-           || __put_user(getparam32.param, &getparam->param)
-           || __put_user((void __user *)(unsigned long)getparam32.value,
-                         &getparam->value))
-               return -EFAULT;
+       getparam.param = getparam32.param;
+       getparam.value = compat_ptr(getparam32.value);
 
-       return drm_ioctl(file, DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
+       return drm_ioctl_kernel(file, r128_getparam, &getparam, DRM_AUTH);
 }
 
 drm_ioctl_compat_t *r128_compat_ioctls[] = {
index 8fd2d9f..8fdc56c 100644 (file)
@@ -1460,7 +1460,7 @@ static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *fi
        return ret;
 }
 
-static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv)
+int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_depth_t *depth = data;
@@ -1492,7 +1492,7 @@ static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *f
        return ret;
 }
 
-static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
+int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_stipple_t *stipple = data;
@@ -1582,7 +1582,7 @@ static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file
        return 0;
 }
 
-static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
+int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_getparam_t *param = data;
index 6f638bb..2cab27a 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/notifier.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/compat.h>
 
 /*
  * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a
@@ -238,46 +239,29 @@ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
 }
 
 static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
-               unsigned long arg)
+               unsigned nmsgs, struct i2c_msg *msgs)
 {
-       struct i2c_rdwr_ioctl_data rdwr_arg;
-       struct i2c_msg *rdwr_pa;
        u8 __user **data_ptrs;
        int i, res;
 
-       if (copy_from_user(&rdwr_arg,
-                          (struct i2c_rdwr_ioctl_data __user *)arg,
-                          sizeof(rdwr_arg)))
-               return -EFAULT;
-
-       /* Put an arbitrary limit on the number of messages that can
-        * be sent at once */
-       if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
-               return -EINVAL;
-
-       rdwr_pa = memdup_user(rdwr_arg.msgs,
-                             rdwr_arg.nmsgs * sizeof(struct i2c_msg));
-       if (IS_ERR(rdwr_pa))
-               return PTR_ERR(rdwr_pa);
-
-       data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
+       data_ptrs = kmalloc(nmsgs * sizeof(u8 __user *), GFP_KERNEL);
        if (data_ptrs == NULL) {
-               kfree(rdwr_pa);
+               kfree(msgs);
                return -ENOMEM;
        }
 
        res = 0;
-       for (i = 0; i < rdwr_arg.nmsgs; i++) {
+       for (i = 0; i < nmsgs; i++) {
                /* Limit the size of the message to a sane amount */
-               if (rdwr_pa[i].len > 8192) {
+               if (msgs[i].len > 8192) {
                        res = -EINVAL;
                        break;
                }
 
-               data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
-               rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len);
-               if (IS_ERR(rdwr_pa[i].buf)) {
-                       res = PTR_ERR(rdwr_pa[i].buf);
+               data_ptrs[i] = (u8 __user *)msgs[i].buf;
+               msgs[i].buf = memdup_user(data_ptrs[i], msgs[i].len);
+               if (IS_ERR(msgs[i].buf)) {
+                       res = PTR_ERR(msgs[i].buf);
                        break;
                }
 
@@ -292,121 +276,117 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
                 * greater (for example to account for a checksum byte at
                 * the end of the message.)
                 */
-               if (rdwr_pa[i].flags & I2C_M_RECV_LEN) {
-                       if (!(rdwr_pa[i].flags & I2C_M_RD) ||
-                           rdwr_pa[i].buf[0] < 1 ||
-                           rdwr_pa[i].len < rdwr_pa[i].buf[0] +
+               if (msgs[i].flags & I2C_M_RECV_LEN) {
+                       if (!(msgs[i].flags & I2C_M_RD) ||
+                           msgs[i].buf[0] < 1 ||
+                           msgs[i].len < msgs[i].buf[0] +
                                             I2C_SMBUS_BLOCK_MAX) {
                                res = -EINVAL;
                                break;
                        }
 
-                       rdwr_pa[i].len = rdwr_pa[i].buf[0];
+                       msgs[i].len = msgs[i].buf[0];
                }
        }
        if (res < 0) {
                int j;
                for (j = 0; j < i; ++j)
-                       kfree(rdwr_pa[j].buf);
+                       kfree(msgs[j].buf);
                kfree(data_ptrs);
-               kfree(rdwr_pa);
+               kfree(msgs);
                return res;
        }
 
-       res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
+       res = i2c_transfer(client->adapter, msgs, nmsgs);
        while (i-- > 0) {
-               if (res >= 0 && (rdwr_pa[i].flags & I2C_M_RD)) {
-                       if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
-                                        rdwr_pa[i].len))
+               if (res >= 0 && (msgs[i].flags & I2C_M_RD)) {
+                       if (copy_to_user(data_ptrs[i], msgs[i].buf,
+                                        msgs[i].len))
                                res = -EFAULT;
                }
-               kfree(rdwr_pa[i].buf);
+               kfree(msgs[i].buf);
        }
        kfree(data_ptrs);
-       kfree(rdwr_pa);
+       kfree(msgs);
        return res;
 }
 
 static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
-               unsigned long arg)
+               u8 read_write, u8 command, u32 size,
+               union i2c_smbus_data __user *data)
 {
-       struct i2c_smbus_ioctl_data data_arg;
        union i2c_smbus_data temp = {};
        int datasize, res;
 
-       if (copy_from_user(&data_arg,
-                          (struct i2c_smbus_ioctl_data __user *) arg,
-                          sizeof(struct i2c_smbus_ioctl_data)))
-               return -EFAULT;
-       if ((data_arg.size != I2C_SMBUS_BYTE) &&
-           (data_arg.size != I2C_SMBUS_QUICK) &&
-           (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
-           (data_arg.size != I2C_SMBUS_WORD_DATA) &&
-           (data_arg.size != I2C_SMBUS_PROC_CALL) &&
-           (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
-           (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
-           (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
-           (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
+       if ((size != I2C_SMBUS_BYTE) &&
+           (size != I2C_SMBUS_QUICK) &&
+           (size != I2C_SMBUS_BYTE_DATA) &&
+           (size != I2C_SMBUS_WORD_DATA) &&
+           (size != I2C_SMBUS_PROC_CALL) &&
+           (size != I2C_SMBUS_BLOCK_DATA) &&
+           (size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
+           (size != I2C_SMBUS_I2C_BLOCK_DATA) &&
+           (size != I2C_SMBUS_BLOCK_PROC_CALL)) {
                dev_dbg(&client->adapter->dev,
                        "size out of range (%x) in ioctl I2C_SMBUS.\n",
-                       data_arg.size);
+                       size);
                return -EINVAL;
        }
        /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
           so the check is valid if size==I2C_SMBUS_QUICK too. */
-       if ((data_arg.read_write != I2C_SMBUS_READ) &&
-           (data_arg.read_write != I2C_SMBUS_WRITE)) {
+       if ((read_write != I2C_SMBUS_READ) &&
+           (read_write != I2C_SMBUS_WRITE)) {
                dev_dbg(&client->adapter->dev,
                        "read_write out of range (%x) in ioctl I2C_SMBUS.\n",
-                       data_arg.read_write);
+                       read_write);
                return -EINVAL;
        }
 
        /* Note that command values are always valid! */
 
-       if ((data_arg.size == I2C_SMBUS_QUICK) ||
-           ((data_arg.size == I2C_SMBUS_BYTE) &&
-           (data_arg.read_write == I2C_SMBUS_WRITE)))
+       if ((size == I2C_SMBUS_QUICK) ||
+           ((size == I2C_SMBUS_BYTE) &&
+           (read_write == I2C_SMBUS_WRITE)))
                /* These are special: we do not use data */
                return i2c_smbus_xfer(client->adapter, client->addr,
-                                     client->flags, data_arg.read_write,
-                                     data_arg.command, data_arg.size, NULL);
+                                     client->flags, read_write,
+                                     command, size, NULL);
 
-       if (data_arg.data == NULL) {
+       if (data == NULL) {
                dev_dbg(&client->adapter->dev,
                        "data is NULL pointer in ioctl I2C_SMBUS.\n");
                return -EINVAL;
        }
 
-       if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
-           (data_arg.size == I2C_SMBUS_BYTE))
-               datasize = sizeof(data_arg.data->byte);
-       else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
-                (data_arg.size == I2C_SMBUS_PROC_CALL))
-               datasize = sizeof(data_arg.data->word);
+       if ((size == I2C_SMBUS_BYTE_DATA) ||
+           (size == I2C_SMBUS_BYTE))
+               datasize = sizeof(data->byte);
+       else if ((size == I2C_SMBUS_WORD_DATA) ||
+                (size == I2C_SMBUS_PROC_CALL))
+               datasize = sizeof(data->word);
        else /* size == smbus block, i2c block, or block proc. call */
-               datasize = sizeof(data_arg.data->block);
+               datasize = sizeof(data->block);
 
-       if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-           (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
-           (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
-           (data_arg.read_write == I2C_SMBUS_WRITE)) {
-               if (copy_from_user(&temp, data_arg.data, datasize))
+       if ((size == I2C_SMBUS_PROC_CALL) ||
+           (size == I2C_SMBUS_BLOCK_PROC_CALL) ||
+           (size == I2C_SMBUS_I2C_BLOCK_DATA) ||
+           (read_write == I2C_SMBUS_WRITE)) {
+               if (copy_from_user(&temp, data, datasize))
                        return -EFAULT;
        }
-       if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
+       if (size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
                /* Convert old I2C block commands to the new
                   convention. This preserves binary compatibility. */
-               data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
-               if (data_arg.read_write == I2C_SMBUS_READ)
+               size = I2C_SMBUS_I2C_BLOCK_DATA;
+               if (read_write == I2C_SMBUS_READ)
                        temp.block[0] = I2C_SMBUS_BLOCK_MAX;
        }
        res = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
-             data_arg.read_write, data_arg.command, data_arg.size, &temp);
-       if (!res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-                    (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
-                    (data_arg.read_write == I2C_SMBUS_READ))) {
-               if (copy_to_user(data_arg.data, &temp, datasize))
+             read_write, command, size, &temp);
+       if (!res && ((size == I2C_SMBUS_PROC_CALL) ||
+                    (size == I2C_SMBUS_BLOCK_PROC_CALL) ||
+                    (read_write == I2C_SMBUS_READ))) {
+               if (copy_to_user(data, &temp, datasize))
                        return -EFAULT;
        }
        return res;
@@ -454,12 +434,39 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                funcs = i2c_get_functionality(client->adapter);
                return put_user(funcs, (unsigned long __user *)arg);
 
-       case I2C_RDWR:
-               return i2cdev_ioctl_rdwr(client, arg);
+       case I2C_RDWR: {
+               struct i2c_rdwr_ioctl_data rdwr_arg;
+               struct i2c_msg *rdwr_pa;
+
+               if (copy_from_user(&rdwr_arg,
+                                  (struct i2c_rdwr_ioctl_data __user *)arg,
+                                  sizeof(rdwr_arg)))
+                       return -EFAULT;
+
+               /* Put an arbitrary limit on the number of messages that can
+                * be sent at once */
+               if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
+                       return -EINVAL;
 
-       case I2C_SMBUS:
-               return i2cdev_ioctl_smbus(client, arg);
+               rdwr_pa = memdup_user(rdwr_arg.msgs,
+                                     rdwr_arg.nmsgs * sizeof(struct i2c_msg));
+               if (IS_ERR(rdwr_pa))
+                       return PTR_ERR(rdwr_pa);
+
+               return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);
+       }
 
+       case I2C_SMBUS: {
+               struct i2c_smbus_ioctl_data data_arg;
+               if (copy_from_user(&data_arg,
+                                  (struct i2c_smbus_ioctl_data __user *) arg,
+                                  sizeof(struct i2c_smbus_ioctl_data)))
+                       return -EFAULT;
+               return i2cdev_ioctl_smbus(client, data_arg.read_write,
+                                         data_arg.command,
+                                         data_arg.size,
+                                         data_arg.data);
+       }
        case I2C_RETRIES:
                client->adapter->retries = arg;
                break;
@@ -480,6 +487,90 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        return 0;
 }
 
+#ifdef CONFIG_COMPAT
+
+struct i2c_smbus_ioctl_data32 {
+       u8 read_write;
+       u8 command;
+       u32 size;
+       compat_caddr_t data; /* union i2c_smbus_data *data */
+};
+
+struct i2c_msg32 {
+       u16 addr;
+       u16 flags;
+       u16 len;
+       compat_caddr_t buf;
+};
+
+struct i2c_rdwr_ioctl_data32 {
+       compat_caddr_t msgs; /* struct i2c_msg __user *msgs */
+       u32 nmsgs;
+};
+
+static long compat_i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct i2c_client *client = file->private_data;
+       unsigned long funcs;
+       switch (cmd) {
+       case I2C_FUNCS:
+               funcs = i2c_get_functionality(client->adapter);
+               return put_user(funcs, (compat_ulong_t __user *)arg);
+       case I2C_RDWR: {
+               struct i2c_rdwr_ioctl_data32 rdwr_arg;
+               struct i2c_msg32 *p;
+               struct i2c_msg *rdwr_pa;
+               int i;
+
+               if (copy_from_user(&rdwr_arg,
+                                  (struct i2c_rdwr_ioctl_data32 __user *)arg,
+                                  sizeof(rdwr_arg)))
+                       return -EFAULT;
+
+               if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
+                       return -EINVAL;
+
+               rdwr_pa = kmalloc_array(rdwr_arg.nmsgs, sizeof(struct i2c_msg),
+                                     GFP_KERNEL);
+               if (!rdwr_pa)
+                       return -ENOMEM;
+
+               p = compat_ptr(rdwr_arg.msgs);
+               for (i = 0; i < rdwr_arg.nmsgs; i++) {
+                       struct i2c_msg32 umsg;
+                       if (copy_from_user(&umsg, p + i, sizeof(umsg))) {
+                               kfree(rdwr_pa);
+                               return -EFAULT;
+                       }
+                       rdwr_pa[i] = (struct i2c_msg) {
+                               .addr = umsg.addr,
+                               .flags = umsg.flags,
+                               .len = umsg.len,
+                               .buf = compat_ptr(umsg.buf)
+                       };
+               }
+
+               return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);
+       }
+       case I2C_SMBUS: {
+               struct i2c_smbus_ioctl_data32   data32;
+               if (copy_from_user(&data32,
+                                  (void __user *) arg,
+                                  sizeof(data32)))
+                       return -EFAULT;
+               return i2cdev_ioctl_smbus(client, data32.read_write,
+                                         data32.command,
+                                         data32.size,
+                                         compat_ptr(data32.data));
+       }
+       default:
+               return i2cdev_ioctl(file, cmd, arg);
+       }
+}
+#else
+#define compat_i2cdev_ioctl NULL
+#endif
+
 static int i2cdev_open(struct inode *inode, struct file *file)
 {
        unsigned int minor = iminor(inode);
@@ -527,6 +618,7 @@ static const struct file_operations i2cdev_fops = {
        .read           = i2cdev_read,
        .write          = i2cdev_write,
        .unlocked_ioctl = i2cdev_ioctl,
+       .compat_ioctl   = compat_i2cdev_ioctl,
        .open           = i2cdev_open,
        .release        = i2cdev_release,
 };
index 3568294..de8c902 100644 (file)
@@ -375,12 +375,7 @@ static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd,
                return -EINVAL;
 
        if (!mtd->_write_oob)
-               ret = -EOPNOTSUPP;
-       else
-               ret = access_ok(VERIFY_READ, ptr, length) ? 0 : -EFAULT;
-
-       if (ret)
-               return ret;
+               return -EOPNOTSUPP;
 
        ops.ooblen = length;
        ops.ooboffs = start & (mtd->writesize - 1);
@@ -419,9 +414,6 @@ static int mtdchar_readoob(struct file *file, struct mtd_info *mtd,
        if (length > 4096)
                return -EINVAL;
 
-       if (!access_ok(VERIFY_WRITE, ptr, length))
-               return -EFAULT;
-
        ops.ooblen = length;
        ops.ooboffs = start & (mtd->writesize - 1);
        ops.datbuf = NULL;
@@ -618,9 +610,6 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd,
 
        usr_data = (const void __user *)(uintptr_t)req.usr_data;
        usr_oob = (const void __user *)(uintptr_t)req.usr_oob;
-       if (!access_ok(VERIFY_READ, usr_data, req.len) ||
-           !access_ok(VERIFY_READ, usr_oob, req.ooblen))
-               return -EFAULT;
 
        if (!mtd->_write_oob)
                return -EOPNOTSUPP;
@@ -662,21 +651,10 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
        struct mtd_info *mtd = mfi->mtd;
        void __user *argp = (void __user *)arg;
        int ret = 0;
-       u_long size;
        struct mtd_info_user info;
 
        pr_debug("MTD_ioctl\n");
 
-       size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
-       if (cmd & IOC_IN) {
-               if (!access_ok(VERIFY_READ, argp, size))
-                       return -EFAULT;
-       }
-       if (cmd & IOC_OUT) {
-               if (!access_ok(VERIFY_WRITE, argp, size))
-                       return -EFAULT;
-       }
-
        switch (cmd) {
        case MEMGETREGIONCOUNT:
                if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
index 6178028..38b3a9c 100644 (file)
@@ -3393,12 +3393,6 @@ static int cxlflash_afu_debug(struct cxlflash_cfg *cfg,
                        goto out;
                }
 
-               if (unlikely(!access_ok(is_write ? VERIFY_READ : VERIFY_WRITE,
-                                       ubuf, ulen))) {
-                       rc = -EFAULT;
-                       goto out;
-               }
-
                buf = kmalloc(ulen + cache_line_size() - 1, GFP_KERNEL);
                if (unlikely(!buf)) {
                        rc = -ENOMEM;
index d946838..2a205c6 100644 (file)
@@ -762,32 +762,15 @@ abort:
 static long
 pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
-       int                     err = 0;
        int                     retval = 0;
        struct pi433_instance   *instance;
        struct pi433_device     *device;
-       u32                     tmp;
+       void __user *argp = (void __user *)arg;
 
        /* Check type and command number */
        if (_IOC_TYPE(cmd) != PI433_IOC_MAGIC)
                return -ENOTTY;
 
-       /* Check access direction once here; don't repeat below.
-        * IOC_DIR is from the user perspective, while access_ok is
-        * from the kernel perspective; so they look reversed.
-        */
-       if (_IOC_DIR(cmd) & _IOC_READ)
-               err = !access_ok(VERIFY_WRITE,
-                                (void __user *)arg,
-                                _IOC_SIZE(cmd));
-
-       if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE)
-               err = !access_ok(VERIFY_READ,
-                                (void __user *)arg,
-                                _IOC_SIZE(cmd));
-       if (err)
-               return -EFAULT;
-
        /* TODO? guard against device removal before, or while,
         * we issue this ioctl. --> device_get()
         */
@@ -799,78 +782,33 @@ pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
        switch (cmd) {
        case PI433_IOC_RD_TX_CFG:
-               tmp = _IOC_SIZE(cmd);
-               if ((tmp == 0) || ((tmp % sizeof(struct pi433_tx_cfg)) != 0)) {
-                       retval = -EINVAL;
-                       break;
-               }
-
-               if (__copy_to_user((void __user *)arg,
-                                   &instance->tx_cfg,
-                                   tmp))
-               {
-                       retval = -EFAULT;
-                       break;
-               }
-
+               if (copy_to_user(argp, &instance->tx_cfg,
+                                       sizeof(struct pi433_tx_cfg)))
+                       return -EFAULT;
                break;
        case PI433_IOC_WR_TX_CFG:
-               tmp = _IOC_SIZE(cmd);
-               if ((tmp == 0) || ((tmp % sizeof(struct pi433_tx_cfg)) != 0)) {
-                       retval = -EINVAL;
-                       break;
-               }
-
-               if (__copy_from_user(&instance->tx_cfg,
-                                    (void __user *)arg,
-                                    tmp))
-               {
-                       retval = -EFAULT;
-                       break;
-               }
-
+               if (copy_from_user(&instance->tx_cfg, argp,
+                                       sizeof(struct pi433_tx_cfg)))
+                       return -EFAULT;
                break;
-
        case PI433_IOC_RD_RX_CFG:
-               tmp = _IOC_SIZE(cmd);
-               if ( (tmp == 0) || ((tmp % sizeof(struct pi433_rx_cfg)) != 0) ) {
-                       retval = -EINVAL;
-                       break;
-               }
-
-               if (__copy_to_user((void __user *)arg,
-                                  &device->rx_cfg,
-                                  tmp))
-               {
-                       retval = -EFAULT;
-                       break;
-               }
-
+               if (copy_to_user(argp, &device->rx_cfg,
+                                       sizeof(struct pi433_rx_cfg)))
+                       return -EFAULT;
                break;
        case PI433_IOC_WR_RX_CFG:
-               tmp = _IOC_SIZE(cmd);
                mutex_lock(&device->rx_lock);
 
                /* during pendig read request, change of config not allowed */
                if (device->rx_active) {
-                       retval = -EAGAIN;
-                       mutex_unlock(&device->rx_lock);
-                       break;
-               }
-
-               if ( (tmp == 0) || ((tmp % sizeof(struct pi433_rx_cfg)) != 0) ) {
-                       retval = -EINVAL;
                        mutex_unlock(&device->rx_lock);
-                       break;
+                       return -EAGAIN;
                }
 
-               if (__copy_from_user(&device->rx_cfg,
-                                    (void __user *)arg,
-                                    tmp))
-               {
-                       retval = -EFAULT;
+               if (copy_from_user(&device->rx_cfg, argp,
+                                       sizeof(struct pi433_rx_cfg))) {
                        mutex_unlock(&device->rx_lock);
-                       break;
+                       return -EFAULT;
                }
 
                mutex_unlock(&device->rx_lock);
index 7a4c802..af4da95 100644 (file)
@@ -156,42 +156,34 @@ static int store_utf8(u16 c, char *p)
 int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
 {
        struct vc_data *vc = vc_cons[fg_console].d;
-       int sel_mode, new_sel_start, new_sel_end, spc;
+       int new_sel_start, new_sel_end, spc;
+       struct tiocl_selection v;
        char *bp, *obp;
        int i, ps, pe, multiplier;
        u16 c;
        int mode;
 
        poke_blanked_console();
+       if (copy_from_user(&v, sel, sizeof(*sel)))
+               return -EFAULT;
 
-       { unsigned short xs, ys, xe, ye;
+       v.xs = limit(v.xs - 1, vc->vc_cols - 1);
+       v.ys = limit(v.ys - 1, vc->vc_rows - 1);
+       v.xe = limit(v.xe - 1, vc->vc_cols - 1);
+       v.ye = limit(v.ye - 1, vc->vc_rows - 1);
+       ps = v.ys * vc->vc_size_row + (v.xs << 1);
+       pe = v.ye * vc->vc_size_row + (v.xe << 1);
 
-         if (!access_ok(VERIFY_READ, sel, sizeof(*sel)))
-               return -EFAULT;
-         __get_user(xs, &sel->xs);
-         __get_user(ys, &sel->ys);
-         __get_user(xe, &sel->xe);
-         __get_user(ye, &sel->ye);
-         __get_user(sel_mode, &sel->sel_mode);
-         xs--; ys--; xe--; ye--;
-         xs = limit(xs, vc->vc_cols - 1);
-         ys = limit(ys, vc->vc_rows - 1);
-         xe = limit(xe, vc->vc_cols - 1);
-         ye = limit(ye, vc->vc_rows - 1);
-         ps = ys * vc->vc_size_row + (xs << 1);
-         pe = ye * vc->vc_size_row + (xe << 1);
-
-         if (sel_mode == TIOCL_SELCLEAR) {
-             /* useful for screendump without selection highlights */
-             clear_selection();
-             return 0;
-         }
-
-         if (mouse_reporting() && (sel_mode & TIOCL_SELMOUSEREPORT)) {
-             mouse_report(tty, sel_mode & TIOCL_SELBUTTONMASK, xs, ys);
-             return 0;
-         }
-        }
+       if (v.sel_mode == TIOCL_SELCLEAR) {
+               /* useful for screendump without selection highlights */
+               clear_selection();
+               return 0;
+       }
+
+       if (mouse_reporting() && (v.sel_mode & TIOCL_SELMOUSEREPORT)) {
+               mouse_report(tty, v.sel_mode & TIOCL_SELBUTTONMASK, v.xs, v.ys);
+               return 0;
+       }
 
        if (ps > pe)    /* make sel_start <= sel_end */
        {
@@ -210,7 +202,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
        else
                use_unicode = 0;
 
-       switch (sel_mode)
+       switch (v.sel_mode)
        {
                case TIOCL_SELCHAR:     /* character-by-character selection */
                        new_sel_start = ps;
index 2d2b420..d61be30 100644 (file)
@@ -843,58 +843,44 @@ int vt_ioctl(struct tty_struct *tty,
 
        case VT_RESIZEX:
        {
-               struct vt_consize __user *vtconsize = up;
-               ushort ll,cc,vlin,clin,vcol,ccol;
+               struct vt_consize v;
                if (!perm)
                        return -EPERM;
-               if (!access_ok(VERIFY_READ, vtconsize,
-                               sizeof(struct vt_consize))) {
-                       ret = -EFAULT;
-                       break;
-               }
+               if (copy_from_user(&v, up, sizeof(struct vt_consize)))
+                       return -EFAULT;
                /* FIXME: Should check the copies properly */
-               __get_user(ll, &vtconsize->v_rows);
-               __get_user(cc, &vtconsize->v_cols);
-               __get_user(vlin, &vtconsize->v_vlin);
-               __get_user(clin, &vtconsize->v_clin);
-               __get_user(vcol, &vtconsize->v_vcol);
-               __get_user(ccol, &vtconsize->v_ccol);
-               vlin = vlin ? vlin : vc->vc_scan_lines;
-               if (clin) {
-                       if (ll) {
-                               if (ll != vlin/clin) {
-                                       /* Parameters don't add up */
-                                       ret = -EINVAL;
-                                       break;
-                               }
-                       } else 
-                               ll = vlin/clin;
+               if (!v.v_vlin)
+                       v.v_vlin = vc->vc_scan_lines;
+               if (v.v_clin) {
+                       int rows = v.v_vlin/v.v_clin;
+                       if (v.v_rows != rows) {
+                               if (v.v_rows) /* Parameters don't add up */
+                                       return -EINVAL;
+                               v.v_rows = rows;
+                       }
                }
-               if (vcol && ccol) {
-                       if (cc) {
-                               if (cc != vcol/ccol) {
-                                       ret = -EINVAL;
-                                       break;
-                               }
-                       } else
-                               cc = vcol/ccol;
+               if (v.v_vcol && v.v_ccol) {
+                       int cols = v.v_vcol/v.v_ccol;
+                       if (v.v_cols != cols) {
+                               if (v.v_cols)
+                                       return -EINVAL;
+                               v.v_cols = cols;
+                       }
                }
 
-               if (clin > 32) {
-                       ret =  -EINVAL;
-                       break;
-               }
-                   
+               if (v.v_clin > 32)
+                       return -EINVAL;
+
                for (i = 0; i < MAX_NR_CONSOLES; i++) {
                        if (!vc_cons[i].d)
                                continue;
                        console_lock();
-                       if (vlin)
-                               vc_cons[i].d->vc_scan_lines = vlin;
-                       if (clin)
-                               vc_cons[i].d->vc_font.height = clin;
+                       if (v.v_vlin)
+                               vc_cons[i].d->vc_scan_lines = v.v_vlin;
+                       if (v.v_clin)
+                               vc_cons[i].d->vc_font.height = v.v_clin;
                        vc_cons[i].d->vc_resize_user = 1;
-                       vc_resize(vc_cons[i].d, cc, ll);
+                       vc_resize(vc_cons[i].d, v.v_cols, v.v_rows);
                        console_unlock();
                }
                break;
index e6de771..a062d75 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1297,20 +1297,10 @@ static bool aio_read_events(struct kioctx *ctx, long min_nr, long nr,
 
 static long read_events(struct kioctx *ctx, long min_nr, long nr,
                        struct io_event __user *event,
-                       struct timespec __user *timeout)
+                       ktime_t until)
 {
-       ktime_t until = KTIME_MAX;
        long ret = 0;
 
-       if (timeout) {
-               struct timespec ts;
-
-               if (unlikely(copy_from_user(&ts, timeout, sizeof(ts))))
-                       return -EFAULT;
-
-               until = timespec_to_ktime(ts);
-       }
-
        /*
         * Note that aio_read_events() is being called as the conditional - i.e.
         * we're calling it after prepare_to_wait() has set task state to
@@ -1826,6 +1816,25 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
        return ret;
 }
 
+static long do_io_getevents(aio_context_t ctx_id,
+               long min_nr,
+               long nr,
+               struct io_event __user *events,
+               struct timespec64 *ts)
+{
+       ktime_t until = ts ? timespec64_to_ktime(*ts) : KTIME_MAX;
+       struct kioctx *ioctx = lookup_ioctx(ctx_id);
+       long ret = -EINVAL;
+
+       if (likely(ioctx)) {
+               if (likely(min_nr <= nr && min_nr >= 0))
+                       ret = read_events(ioctx, min_nr, nr, events, until);
+               percpu_ref_put(&ioctx->users);
+       }
+
+       return ret;
+}
+
 /* io_getevents:
  *     Attempts to read at least min_nr events and up to nr events from
  *     the completion queue for the aio_context specified by ctx_id. If
@@ -1844,15 +1853,14 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
                struct io_event __user *, events,
                struct timespec __user *, timeout)
 {
-       struct kioctx *ioctx = lookup_ioctx(ctx_id);
-       long ret = -EINVAL;
+       struct timespec64       ts;
 
-       if (likely(ioctx)) {
-               if (likely(min_nr <= nr && min_nr >= 0))
-                       ret = read_events(ioctx, min_nr, nr, events, timeout);
-               percpu_ref_put(&ioctx->users);
+       if (timeout) {
+               if (unlikely(get_timespec64(&ts, timeout)))
+                       return -EFAULT;
        }
-       return ret;
+
+       return do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
 }
 
 #ifdef CONFIG_COMPAT
@@ -1862,17 +1870,14 @@ COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
                       struct io_event __user *, events,
                       struct compat_timespec __user *, timeout)
 {
-       struct timespec t;
-       struct timespec __user *ut = NULL;
+       struct timespec64 t;
 
        if (timeout) {
-               if (compat_get_timespec(&t, timeout))
+               if (compat_get_timespec64(&t, timeout))
                        return -EFAULT;
 
-               ut = compat_alloc_user_space(sizeof(*ut));
-               if (copy_to_user(ut, &t, sizeof(t)))
-                       return -EFAULT;
        }
-       return sys_io_getevents(ctx_id, min_nr, nr, events, ut);
+
+       return do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
 }
 #endif
index bd5d91e..f95aa0b 100644 (file)
@@ -54,8 +54,6 @@
 #include <linux/if_tun.h>
 #include <linux/ctype.h>
 #include <linux/syscalls.h>
-#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
 #include <linux/atalk.h>
 #include <linux/gfp.h>
 #include <linux/cec.h>
@@ -137,22 +135,6 @@ static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        return vfs_ioctl(file, cmd, arg);
 }
 
-static int w_long(struct file *file,
-               unsigned int cmd, compat_ulong_t __user *argp)
-{
-       int err;
-       unsigned long __user *valp = compat_alloc_user_space(sizeof(*valp));
-
-       if (valp == NULL)
-               return -EFAULT;
-       err = do_ioctl(file, cmd, (unsigned long)valp);
-       if (err)
-               return err;
-       if (convert_in_user(valp, argp))
-               return -EFAULT;
-       return 0;
-}
-
 struct compat_video_event {
        int32_t         type;
        compat_time_t   timestamp;
@@ -671,96 +653,6 @@ static int serial_struct_ioctl(struct file *file,
         return err;
 }
 
-/*
- * I2C layer ioctls
- */
-
-struct i2c_msg32 {
-       u16 addr;
-       u16 flags;
-       u16 len;
-       compat_caddr_t buf;
-};
-
-struct i2c_rdwr_ioctl_data32 {
-       compat_caddr_t msgs; /* struct i2c_msg __user *msgs */
-       u32 nmsgs;
-};
-
-struct i2c_smbus_ioctl_data32 {
-       u8 read_write;
-       u8 command;
-       u32 size;
-       compat_caddr_t data; /* union i2c_smbus_data *data */
-};
-
-struct i2c_rdwr_aligned {
-       struct i2c_rdwr_ioctl_data cmd;
-       struct i2c_msg msgs[0];
-};
-
-static int do_i2c_rdwr_ioctl(struct file *file,
-       unsigned int cmd, struct i2c_rdwr_ioctl_data32 __user *udata)
-{
-       struct i2c_rdwr_aligned         __user *tdata;
-       struct i2c_msg                  __user *tmsgs;
-       struct i2c_msg32                __user *umsgs;
-       compat_caddr_t                  datap;
-       u32                             nmsgs;
-       int                             i;
-
-       if (get_user(nmsgs, &udata->nmsgs))
-               return -EFAULT;
-       if (nmsgs > I2C_RDWR_IOCTL_MAX_MSGS)
-               return -EINVAL;
-
-       if (get_user(datap, &udata->msgs))
-               return -EFAULT;
-       umsgs = compat_ptr(datap);
-
-       tdata = compat_alloc_user_space(sizeof(*tdata) +
-                                     nmsgs * sizeof(struct i2c_msg));
-       tmsgs = &tdata->msgs[0];
-
-       if (put_user(nmsgs, &tdata->cmd.nmsgs) ||
-           put_user(tmsgs, &tdata->cmd.msgs))
-               return -EFAULT;
-
-       for (i = 0; i < nmsgs; i++) {
-               if (copy_in_user(&tmsgs[i].addr, &umsgs[i].addr, 3*sizeof(u16)))
-                       return -EFAULT;
-               if (get_user(datap, &umsgs[i].buf) ||
-                   put_user(compat_ptr(datap), &tmsgs[i].buf))
-                       return -EFAULT;
-       }
-       return do_ioctl(file, cmd, (unsigned long)tdata);
-}
-
-static int do_i2c_smbus_ioctl(struct file *file,
-               unsigned int cmd, struct i2c_smbus_ioctl_data32   __user *udata)
-{
-       struct i2c_smbus_ioctl_data     __user *tdata;
-       union {
-               /* beginnings of those have identical layouts */
-               struct i2c_smbus_ioctl_data32   data32;
-               struct i2c_smbus_ioctl_data     data;
-       } v;
-
-       tdata = compat_alloc_user_space(sizeof(*tdata));
-       if (tdata == NULL)
-               return -ENOMEM;
-
-       memset(&v, 0, sizeof(v));
-       if (copy_from_user(&v.data32, udata, sizeof(v.data32)))
-               return -EFAULT;
-       v.data.data = compat_ptr(v.data32.data);
-
-       if (copy_to_user(tdata, &v.data, sizeof(v.data)))
-               return -EFAULT;
-
-       return do_ioctl(file, cmd, (unsigned long)tdata);
-}
-
 #define RTC_IRQP_READ32                _IOR('p', 0x0b, compat_ulong_t)
 #define RTC_IRQP_SET32         _IOW('p', 0x0c, compat_ulong_t)
 #define RTC_EPOCH_READ32       _IOR('p', 0x0d, compat_ulong_t)
@@ -1283,13 +1175,6 @@ COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
 COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
 COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
 COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
-/* i2c */
-COMPATIBLE_IOCTL(I2C_SLAVE)
-COMPATIBLE_IOCTL(I2C_SLAVE_FORCE)
-COMPATIBLE_IOCTL(I2C_TENBIT)
-COMPATIBLE_IOCTL(I2C_PEC)
-COMPATIBLE_IOCTL(I2C_RETRIES)
-COMPATIBLE_IOCTL(I2C_TIMEOUT)
 /* hiddev */
 COMPATIBLE_IOCTL(HIDIOCGVERSION)
 COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
@@ -1464,13 +1349,6 @@ static long do_ioctl_trans(unsigned int cmd,
        case TIOCGSERIAL:
        case TIOCSSERIAL:
                return serial_struct_ioctl(file, cmd, argp);
-       /* i2c */
-       case I2C_FUNCS:
-               return w_long(file, cmd, argp);
-       case I2C_RDWR:
-               return do_i2c_rdwr_ioctl(file, cmd, argp);
-       case I2C_SMBUS:
-               return do_i2c_smbus_ioctl(file, cmd, argp);
        /* Not implemented in the native kernel */
        case RTC_IRQP_READ32:
        case RTC_IRQP_SET32:
index 52c63d6..1e2c87a 100644 (file)
@@ -680,16 +680,11 @@ void do_coredump(const siginfo_t *siginfo)
                 * privs and don't want to unlink another user's coredump.
                 */
                if (!need_suid_safe) {
-                       mm_segment_t old_fs;
-
-                       old_fs = get_fs();
-                       set_fs(KERNEL_DS);
                        /*
                         * If it doesn't exist, that's fine. If there's some
                         * other problem, we'll catch it at the filp_open().
                         */
-                       (void) sys_unlink((const char __user *)cn.corename);
-                       set_fs(old_fs);
+                       do_unlinkat(AT_FDCWD, getname_kernel(cn.corename));
                }
 
                /*
index 2fabd19..396a3c0 100644 (file)
@@ -2259,7 +2259,6 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
                        compat_size_t, sigsetsize)
 {
        long err;
-       compat_sigset_t csigmask;
        sigset_t ksigmask, sigsaved;
 
        /*
@@ -2269,9 +2268,8 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
        if (sigmask) {
                if (sigsetsize != sizeof(compat_sigset_t))
                        return -EINVAL;
-               if (copy_from_user(&csigmask, sigmask, sizeof(csigmask)))
+               if (get_compat_sigset(&ksigmask, sigmask))
                        return -EFAULT;
-               sigset_from_compat(&ksigmask, &csigmask);
                sigsaved = current->blocked;
                set_current_blocked(&ksigmask);
        }
index b7558f2..1eec250 100644 (file)
@@ -592,6 +592,44 @@ static int ext4_ioc_getfsmap(struct super_block *sb,
        return 0;
 }
 
+static long ext4_ioctl_group_add(struct file *file,
+                                struct ext4_new_group_data *input)
+{
+       struct super_block *sb = file_inode(file)->i_sb;
+       int err, err2=0;
+
+       err = ext4_resize_begin(sb);
+       if (err)
+               return err;
+
+       if (ext4_has_feature_bigalloc(sb)) {
+               ext4_msg(sb, KERN_ERR,
+                        "Online resizing not supported with bigalloc");
+               err = -EOPNOTSUPP;
+               goto group_add_out;
+       }
+
+       err = mnt_want_write_file(file);
+       if (err)
+               goto group_add_out;
+
+       err = ext4_group_add(sb, input);
+       if (EXT4_SB(sb)->s_journal) {
+               jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
+               err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
+               jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+       }
+       if (err == 0)
+               err = err2;
+       mnt_drop_write_file(file);
+       if (!err && ext4_has_group_desc_csum(sb) &&
+           test_opt(sb, INIT_INODE_TABLE))
+               err = ext4_register_li_request(sb, input->group);
+group_add_out:
+       ext4_resize_end(sb);
+       return err;
+}
+
 long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = file_inode(filp);
@@ -776,44 +814,12 @@ mext_out:
 
        case EXT4_IOC_GROUP_ADD: {
                struct ext4_new_group_data input;
-               int err, err2=0;
-
-               err = ext4_resize_begin(sb);
-               if (err)
-                       return err;
 
                if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
-                               sizeof(input))) {
-                       err = -EFAULT;
-                       goto group_add_out;
-               }
-
-               if (ext4_has_feature_bigalloc(sb)) {
-                       ext4_msg(sb, KERN_ERR,
-                                "Online resizing not supported with bigalloc");
-                       err = -EOPNOTSUPP;
-                       goto group_add_out;
-               }
-
-               err = mnt_want_write_file(filp);
-               if (err)
-                       goto group_add_out;
+                               sizeof(input)))
+                       return -EFAULT;
 
-               err = ext4_group_add(sb, &input);
-               if (EXT4_SB(sb)->s_journal) {
-                       jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
-                       err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
-                       jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
-               }
-               if (err == 0)
-                       err = err2;
-               mnt_drop_write_file(filp);
-               if (!err && ext4_has_group_desc_csum(sb) &&
-                   test_opt(sb, INIT_INODE_TABLE))
-                       err = ext4_register_li_request(sb, input.group);
-group_add_out:
-               ext4_resize_end(sb);
-               return err;
+               return ext4_ioctl_group_add(filp, &input);
        }
 
        case EXT4_IOC_MIGRATE:
@@ -1078,8 +1084,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                break;
        case EXT4_IOC32_GROUP_ADD: {
                struct compat_ext4_new_group_input __user *uinput;
-               struct ext4_new_group_input input;
-               mm_segment_t old_fs;
+               struct ext4_new_group_data input;
                int err;
 
                uinput = compat_ptr(arg);
@@ -1092,12 +1097,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                &uinput->reserved_blocks);
                if (err)
                        return -EFAULT;
-               old_fs = get_fs();
-               set_fs(KERNEL_DS);
-               err = ext4_ioctl(file, EXT4_IOC_GROUP_ADD,
-                                (unsigned long) &input);
-               set_fs(old_fs);
-               return err;
+               return ext4_ioctl_group_add(file, &input);
        }
        case EXT4_IOC_MOVE_EXT:
        case EXT4_IOC_RESIZE_FS:
index 48cee21..df262f4 100644 (file)
@@ -55,6 +55,7 @@ extern void __init chrdev_init(void);
 extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *);
 extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
                           const char *, unsigned int, struct path *);
+long do_unlinkat(int dfd, struct filename *name);
 
 /*
  * namespace.c
index 5424b10..2877813 100644 (file)
@@ -4010,10 +4010,9 @@ EXPORT_SYMBOL(vfs_unlink);
  * writeout happening, and we don't want to prevent access to the directory
  * while waiting on the I/O.
  */
-static long do_unlinkat(int dfd, const char __user *pathname)
+long do_unlinkat(int dfd, struct filename *name)
 {
        int error;
-       struct filename *name;
        struct dentry *dentry;
        struct path path;
        struct qstr last;
@@ -4022,8 +4021,7 @@ static long do_unlinkat(int dfd, const char __user *pathname)
        struct inode *delegated_inode = NULL;
        unsigned int lookup_flags = 0;
 retry:
-       name = filename_parentat(dfd, getname(pathname), lookup_flags,
-                               &path, &last, &type);
+       name = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
        if (IS_ERR(name))
                return PTR_ERR(name);
 
@@ -4065,12 +4063,12 @@ exit2:
        mnt_drop_write(path.mnt);
 exit1:
        path_put(&path);
-       putname(name);
        if (retry_estale(error, lookup_flags)) {
                lookup_flags |= LOOKUP_REVAL;
                inode = NULL;
                goto retry;
        }
+       putname(name);
        return error;
 
 slashes:
@@ -4091,12 +4089,12 @@ SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
        if (flag & AT_REMOVEDIR)
                return do_rmdir(dfd, pathname);
 
-       return do_unlinkat(dfd, pathname);
+       return do_unlinkat(dfd, getname(pathname));
 }
 
 SYSCALL_DEFINE1(unlink, const char __user *, pathname)
 {
-       return do_unlinkat(AT_FDCWD, pathname);
+       return do_unlinkat(AT_FDCWD, getname(pathname));
 }
 
 int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
index 063067e..6de493b 100644 (file)
@@ -292,8 +292,7 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
                                      void __user *p,
                                      int timeval, int ret)
 {
-       struct timespec64 rts64;
-       struct timespec rts;
+       struct timespec64 rts;
        struct timeval rtv;
 
        if (!p)
@@ -306,23 +305,22 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
        if (!end_time->tv_sec && !end_time->tv_nsec)
                return ret;
 
-       ktime_get_ts64(&rts64);
-       rts64 = timespec64_sub(*end_time, rts64);
-       if (rts64.tv_sec < 0)
-               rts64.tv_sec = rts64.tv_nsec = 0;
+       ktime_get_ts64(&rts);
+       rts = timespec64_sub(*end_time, rts);
+       if (rts.tv_sec < 0)
+               rts.tv_sec = rts.tv_nsec = 0;
 
-       rts = timespec64_to_timespec(rts64);
 
        if (timeval) {
                if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
                        memset(&rtv, 0, sizeof(rtv));
-               rtv.tv_sec = rts64.tv_sec;
-               rtv.tv_usec = rts64.tv_nsec / NSEC_PER_USEC;
+               rtv.tv_sec = rts.tv_sec;
+               rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
 
                if (!copy_to_user(p, &rtv, sizeof(rtv)))
                        return ret;
 
-       } else if (!copy_to_user(p, &rts, sizeof(rts)))
+       } else if (!put_timespec64(&rts, p))
                return ret;
 
        /*
@@ -705,17 +703,15 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
                       const sigset_t __user *sigmask, size_t sigsetsize)
 {
        sigset_t ksigmask, sigsaved;
-       struct timespec ts;
-       struct timespec64 ts64, end_time, *to = NULL;
+       struct timespec64 ts, end_time, *to = NULL;
        int ret;
 
        if (tsp) {
-               if (copy_from_user(&ts, tsp, sizeof(ts)))
+               if (get_timespec64(&ts, tsp))
                        return -EFAULT;
-               ts64 = timespec_to_timespec64(ts);
 
                to = &end_time;
-               if (poll_select_set_timeout(to, ts64.tv_sec, ts64.tv_nsec))
+               if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
                        return -EINVAL;
        }
 
@@ -1052,12 +1048,11 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
                size_t, sigsetsize)
 {
        sigset_t ksigmask, sigsaved;
-       struct timespec ts;
-       struct timespec64 end_time, *to = NULL;
+       struct timespec64 ts, end_time, *to = NULL;
        int ret;
 
        if (tsp) {
-               if (copy_from_user(&ts, tsp, sizeof(ts)))
+               if (get_timespec64(&ts, tsp))
                        return -EFAULT;
 
                to = &end_time;
@@ -1103,10 +1098,10 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
 #define __COMPAT_NFDBITS       (8 * sizeof(compat_ulong_t))
 
 static
-int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
+int compat_poll_select_copy_remaining(struct timespec64 *end_time, void __user *p,
                                      int timeval, int ret)
 {
-       struct timespec ts;
+       struct timespec64 ts;
 
        if (!p)
                return ret;
@@ -1118,8 +1113,8 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
        if (!end_time->tv_sec && !end_time->tv_nsec)
                return ret;
 
-       ktime_get_ts(&ts);
-       ts = timespec_sub(*end_time, ts);
+       ktime_get_ts64(&ts);
+       ts = timespec64_sub(*end_time, ts);
        if (ts.tv_sec < 0)
                ts.tv_sec = ts.tv_nsec = 0;
 
@@ -1132,12 +1127,7 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
                if (!copy_to_user(p, &rtv, sizeof(rtv)))
                        return ret;
        } else {
-               struct compat_timespec rts;
-
-               rts.tv_sec = ts.tv_sec;
-               rts.tv_nsec = ts.tv_nsec;
-
-               if (!copy_to_user(p, &rts, sizeof(rts)))
+               if (!compat_put_timespec64(&ts, p))
                        return ret;
        }
        /*
@@ -1195,7 +1185,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
  */
 static int compat_core_sys_select(int n, compat_ulong_t __user *inp,
        compat_ulong_t __user *outp, compat_ulong_t __user *exp,
-       struct timespec *end_time)
+       struct timespec64 *end_time)
 {
        fd_set_bits fds;
        void *bits;
@@ -1268,7 +1258,7 @@ COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
        compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
        struct compat_timeval __user *, tvp)
 {
-       struct timespec end_time, *to = NULL;
+       struct timespec64 end_time, *to = NULL;
        struct compat_timeval tv;
        int ret;
 
@@ -1312,14 +1302,12 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
        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 timespec end_time, *to = NULL;
+       struct timespec64 ts, end_time, *to = NULL;
        int ret;
 
        if (tsp) {
-               if (copy_from_user(&ts, tsp, sizeof(ts)))
+               if (compat_get_timespec64(&ts, tsp))
                        return -EFAULT;
 
                to = &end_time;
@@ -1330,9 +1318,8 @@ 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)))
+               if (get_compat_sigset(&ksigmask, sigmask))
                        return -EFAULT;
-               sigset_from_compat(&ksigmask, &ss32);
 
                sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
                sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
@@ -1381,14 +1368,12 @@ 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 timespec end_time, *to = NULL;
+       struct timespec64 ts, end_time, *to = NULL;
        int ret;
 
        if (tsp) {
-               if (copy_from_user(&ts, tsp, sizeof(ts)))
+               if (compat_get_timespec64(&ts, tsp))
                        return -EFAULT;
 
                to = &end_time;
@@ -1399,9 +1384,8 @@ 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)))
+               if (get_compat_sigset(&ksigmask, sigmask))
                        return -EFAULT;
-               sigset_from_compat(&ksigmask, &ss32);
 
                sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
                sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
index 1c667af..5f1ff87 100644 (file)
@@ -313,15 +313,13 @@ COMPAT_SYSCALL_DEFINE4(signalfd4, int, ufd,
                     compat_size_t, sigsetsize,
                     int, flags)
 {
-       compat_sigset_t ss32;
        sigset_t tmp;
        sigset_t __user *ksigmask;
 
        if (sigsetsize != sizeof(compat_sigset_t))
                return -EINVAL;
-       if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
+       if (get_compat_sigset(&tmp, sigmask))
                return -EFAULT;
-       sigset_from_compat(&tmp, &ss32);
        ksigmask = compat_alloc_user_space(sizeof(sigset_t));
        if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t)))
                return -EFAULT;
index 3e838a8..0fc3640 100644 (file)
@@ -444,11 +444,6 @@ static inline int compat_timespec_compare(struct compat_timespec *lhs,
        return lhs->tv_nsec - rhs->tv_nsec;
 }
 
-extern int get_compat_itimerspec(struct itimerspec *dst,
-                                const struct compat_itimerspec __user *src);
-extern int put_compat_itimerspec(struct compat_itimerspec __user *dst,
-                                const struct itimerspec *src);
-
 asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
                struct timezone __user *tz);
 asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
@@ -456,8 +451,9 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
 
 asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
 
-extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat);
-extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set);
+extern int get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat);
+extern int put_compat_sigset(compat_sigset_t __user *compat,
+                            const sigset_t *set, unsigned int size);
 
 asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
                compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes,
index 772e038..d1cee65 100644 (file)
@@ -367,24 +367,6 @@ COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t,  pid, unsigned int, len,
        return ret;
 }
 
-int get_compat_itimerspec(struct itimerspec *dst,
-                         const struct compat_itimerspec __user *src)
-{
-       if (__compat_get_timespec(&dst->it_interval, &src->it_interval) ||
-           __compat_get_timespec(&dst->it_value, &src->it_value))
-               return -EFAULT;
-       return 0;
-}
-
-int put_compat_itimerspec(struct compat_itimerspec __user *dst,
-                         const struct itimerspec *src)
-{
-       if (__compat_put_timespec(&src->it_interval, &dst->it_interval) ||
-           __compat_put_timespec(&src->it_value, &dst->it_value))
-               return -EFAULT;
-       return 0;
-}
-
 int get_compat_itimerspec64(struct itimerspec64 *its,
                        const struct compat_itimerspec __user *uits)
 {
@@ -485,27 +467,44 @@ Efault:
        return -EFAULT;
 }
 
-void
-sigset_from_compat(sigset_t *set, const compat_sigset_t *compat)
+int
+get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat)
 {
+#ifdef __BIG_ENDIAN
+       compat_sigset_t v;
+       if (copy_from_user(&v, compat, sizeof(compat_sigset_t)))
+               return -EFAULT;
        switch (_NSIG_WORDS) {
-       case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32 );
-       case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32 );
-       case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32 );
-       case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32 );
+       case 4: set->sig[3] = v.sig[6] | (((long)v.sig[7]) << 32 );
+       case 3: set->sig[2] = v.sig[4] | (((long)v.sig[5]) << 32 );
+       case 2: set->sig[1] = v.sig[2] | (((long)v.sig[3]) << 32 );
+       case 1: set->sig[0] = v.sig[0] | (((long)v.sig[1]) << 32 );
        }
+#else
+       if (copy_from_user(set, compat, sizeof(compat_sigset_t)))
+               return -EFAULT;
+#endif
+       return 0;
 }
-EXPORT_SYMBOL_GPL(sigset_from_compat);
+EXPORT_SYMBOL_GPL(get_compat_sigset);
 
-void
-sigset_to_compat(compat_sigset_t *compat, const sigset_t *set)
+int
+put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set,
+                 unsigned int size)
 {
+       /* size <= sizeof(compat_sigset_t) <= sizeof(sigset_t) */
+#ifdef __BIG_ENDIAN
+       compat_sigset_t v;
        switch (_NSIG_WORDS) {
-       case 4: compat->sig[7] = (set->sig[3] >> 32); compat->sig[6] = set->sig[3];
-       case 3: compat->sig[5] = (set->sig[2] >> 32); compat->sig[4] = set->sig[2];
-       case 2: compat->sig[3] = (set->sig[1] >> 32); compat->sig[2] = set->sig[1];
-       case 1: compat->sig[1] = (set->sig[0] >> 32); compat->sig[0] = set->sig[0];
+       case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3];
+       case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2];
+       case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1];
+       case 1: v.sig[1] = (set->sig[0] >> 32); v.sig[0] = set->sig[0];
        }
+       return copy_to_user(compat, &v, size) ? -EFAULT : 0;
+#else
+       return copy_to_user(compat, set, size) ? -EFAULT : 0;
+#endif
 }
 
 #ifdef CONFIG_NUMA
@@ -563,22 +562,6 @@ COMPAT_SYSCALL_DEFINE4(migrate_pages, compat_pid_t, pid,
 }
 #endif
 
-COMPAT_SYSCALL_DEFINE2(sched_rr_get_interval,
-                      compat_pid_t, pid,
-                      struct compat_timespec __user *, interval)
-{
-       struct timespec t;
-       int ret;
-       mm_segment_t old_fs = get_fs();
-
-       set_fs(KERNEL_DS);
-       ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
-       set_fs(old_fs);
-       if (compat_put_timespec(&t, interval))
-               return -EFAULT;
-       return ret;
-}
-
 /*
  * Allocate user-space memory for the duration of a single system call,
  * in order to marshall parameters inside a compat thunk.
index a092f35..75554f3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init_task.h>
 #include <linux/context_tracking.h>
 #include <linux/rcupdate_wait.h>
+#include <linux/compat.h>
 
 #include <linux/blkdev.h>
 #include <linux/kprobes.h>
@@ -5107,13 +5108,11 @@ SYSCALL_DEFINE1(sched_get_priority_min, int, policy)
  * Return: On success, 0 and the timeslice is in @interval. Otherwise,
  * an error code.
  */
-SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
-               struct timespec __user *, interval)
+static int sched_rr_get_interval(pid_t pid, struct timespec64 *t)
 {
        struct task_struct *p;
        unsigned int time_slice;
        struct rq_flags rf;
-       struct timespec t;
        struct rq *rq;
        int retval;
 
@@ -5137,15 +5136,40 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
        task_rq_unlock(rq, p, &rf);
 
        rcu_read_unlock();
-       jiffies_to_timespec(time_slice, &t);
-       retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
-       return retval;
+       jiffies_to_timespec64(time_slice, t);
+       return 0;
 
 out_unlock:
        rcu_read_unlock();
        return retval;
 }
 
+SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
+               struct timespec __user *, interval)
+{
+       struct timespec64 t;
+       int retval = sched_rr_get_interval(pid, &t);
+
+       if (retval == 0)
+               retval = put_timespec64(&t, interval);
+
+       return retval;
+}
+
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE2(sched_rr_get_interval,
+                      compat_pid_t, pid,
+                      struct compat_timespec __user *, interval)
+{
+       struct timespec64 t;
+       int retval = sched_rr_get_interval(pid, &t);
+
+       if (retval == 0)
+               retval = compat_put_timespec64(&t, interval);
+       return retval;
+}
+#endif
+
 void sched_show_task(struct task_struct *p)
 {
        unsigned long free = 0;
index aa1fb9f..babb36d 100644 (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
 
index 2dd1a9c..f169ecc 100644 (file)
@@ -2724,7 +2724,6 @@ static long kvm_vcpu_compat_ioctl(struct file *filp,
        case KVM_SET_SIGNAL_MASK: {
                struct kvm_signal_mask __user *sigmask_arg = argp;
                struct kvm_signal_mask kvm_sigmask;
-               compat_sigset_t csigset;
                sigset_t sigset;
 
                if (argp) {
@@ -2733,13 +2732,11 @@ static long kvm_vcpu_compat_ioctl(struct file *filp,
                                           sizeof(kvm_sigmask)))
                                goto out;
                        r = -EINVAL;
-                       if (kvm_sigmask.len != sizeof(csigset))
+                       if (kvm_sigmask.len != sizeof(compat_sigset_t))
                                goto out;
                        r = -EFAULT;
-                       if (copy_from_user(&csigset, sigmask_arg->sigset,
-                                          sizeof(csigset)))
+                       if (get_compat_sigset(&sigset, (void *)sigmask_arg->sigset))
                                goto out;
-                       sigset_from_compat(&sigset, &csigset);
                        r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
                } else
                        r = kvm_vcpu_ioctl_set_sigmask(vcpu, NULL);