summaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/comedi_fops.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2020-04-25 18:44:30 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2020-05-28 20:31:19 -0400
commit388138764e2549520afd0b3b4e15de8deb592ff6 (patch)
tree7a7889e0953e8727934b7072ed0ccaccceb9229f /drivers/staging/comedi/comedi_fops.c
parent3fbfd2223a271426509830e6340c386a1054cfad (diff)
comedi: get rid of compat_alloc_user_space() mess in COMEDI_RANGEINFO compat
Just take copy_from_user() out of do_rangeing_ioctl() into the caller and have compat_rangeinfo() build a native version and pass it to do_rangeinfo_ioctl() directly. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r--drivers/staging/comedi/comedi_fops.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index ab811735cd1b..d96dc85d8a98 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2210,9 +2210,14 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
rc = do_chaninfo_ioctl(dev, &it);
break;
}
- case COMEDI_RANGEINFO:
- rc = do_rangeinfo_ioctl(dev, (void __user *)arg);
+ case COMEDI_RANGEINFO: {
+ struct comedi_rangeinfo it;
+ if (copy_from_user(&it, (void __user *)arg, sizeof(it)))
+ rc = -EFAULT;
+ else
+ rc = do_rangeinfo_ioctl(dev, &it);
break;
+ }
case COMEDI_BUFINFO:
rc = do_bufinfo_ioctl(dev,
(struct comedi_bufinfo __user *)arg,
@@ -2900,32 +2905,22 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
/* Handle 32-bit COMEDI_RANGEINFO ioctl. */
static int compat_rangeinfo(struct file *file, unsigned long arg)
{
- struct comedi_rangeinfo __user *rangeinfo;
- struct comedi32_rangeinfo_struct __user *rangeinfo32;
+ struct comedi_file *cfp = file->private_data;
+ struct comedi_device *dev = cfp->dev;
+ struct comedi32_rangeinfo_struct rangeinfo32;
+ struct comedi_rangeinfo rangeinfo;
int err;
- union {
- unsigned int uint;
- compat_uptr_t uptr;
- } temp;
-
- rangeinfo32 = compat_ptr(arg);
- rangeinfo = compat_alloc_user_space(sizeof(*rangeinfo));
- /* Copy rangeinfo structure. */
- if (!access_ok(rangeinfo32, sizeof(*rangeinfo32)) ||
- !access_ok(rangeinfo, sizeof(*rangeinfo)))
+ if (copy_from_user(&rangeinfo32, compat_ptr(arg), sizeof(rangeinfo32)))
return -EFAULT;
+ memset(&rangeinfo, 0, sizeof(rangeinfo));
+ rangeinfo.range_type = rangeinfo32.range_type;
+ rangeinfo.range_ptr = compat_ptr(rangeinfo32.range_ptr);
- err = 0;
- err |= __get_user(temp.uint, &rangeinfo32->range_type);
- err |= __put_user(temp.uint, &rangeinfo->range_type);
- err |= __get_user(temp.uptr, &rangeinfo32->range_ptr);
- err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr);
- if (err)
- return -EFAULT;
-
- return comedi_unlocked_ioctl(file, COMEDI_RANGEINFO,
- (unsigned long)rangeinfo);
+ mutex_lock(&dev->mutex);
+ err = do_rangeinfo_ioctl(dev, &rangeinfo);
+ mutex_unlock(&dev->mutex);
+ return err;
}
/* Copy 32-bit cmd structure to native cmd structure. */