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

Pull compat and uaccess updates from Al Viro:

 - {get,put}_compat_sigset() series

 - assorted compat ioctl stuff

 - more set_fs() elimination

 - a few more timespec64 conversions

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

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

View File

@@ -14,45 +14,16 @@
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 */

View 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
{

View File

@@ -46,19 +46,6 @@
#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)

View 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);

View File

@@ -94,40 +94,13 @@
*/
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)

View 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;

View 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,

View 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)

View 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);
/*

View 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);

View 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;
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(file, DRM_IOCTL_R128_INIT, (unsigned long)init);
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[] = {

View 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;

View 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;
case I2C_SMBUS:
return i2cdev_ioctl_smbus(client, arg);
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);
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,
};

View 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)))

View 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;

View 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;
return -EAGAIN;
}
if ( (tmp == 0) || ((tmp % sizeof(struct pi433_rx_cfg)) != 0) ) {
retval = -EINVAL;
if (copy_from_user(&device->rx_cfg, argp,
sizeof(struct pi433_rx_cfg))) {
mutex_unlock(&device->rx_lock);
break;
}
if (__copy_from_user(&device->rx_cfg,
(void __user *)arg,
tmp))
{
retval = -EFAULT;
mutex_unlock(&device->rx_lock);
break;
return -EFAULT;
}
mutex_unlock(&device->rx_lock);

View 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();
{ unsigned short xs, ys, xe, ye;
if (!access_ok(VERIFY_READ, sel, sizeof(*sel)))
if (copy_from_user(&v, 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;
}
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 (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;

View 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;

View File

@@ -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

View 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:

Some files were not shown because too many files have changed in this diff Show More