Skip to content

Commit 3881387

Browse files
author
Al Viro
committed
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 <[email protected]>
1 parent 3fbfd22 commit 3881387

File tree

3 files changed

+27
-35
lines changed

3 files changed

+27
-35
lines changed

drivers/staging/comedi/comedi_fops.c

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,9 +2210,14 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
22102210
rc = do_chaninfo_ioctl(dev, &it);
22112211
break;
22122212
}
2213-
case COMEDI_RANGEINFO:
2214-
rc = do_rangeinfo_ioctl(dev, (void __user *)arg);
2213+
case COMEDI_RANGEINFO: {
2214+
struct comedi_rangeinfo it;
2215+
if (copy_from_user(&it, (void __user *)arg, sizeof(it)))
2216+
rc = -EFAULT;
2217+
else
2218+
rc = do_rangeinfo_ioctl(dev, &it);
22152219
break;
2220+
}
22162221
case COMEDI_BUFINFO:
22172222
rc = do_bufinfo_ioctl(dev,
22182223
(struct comedi_bufinfo __user *)arg,
@@ -2900,32 +2905,22 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
29002905
/* Handle 32-bit COMEDI_RANGEINFO ioctl. */
29012906
static int compat_rangeinfo(struct file *file, unsigned long arg)
29022907
{
2903-
struct comedi_rangeinfo __user *rangeinfo;
2904-
struct comedi32_rangeinfo_struct __user *rangeinfo32;
2908+
struct comedi_file *cfp = file->private_data;
2909+
struct comedi_device *dev = cfp->dev;
2910+
struct comedi32_rangeinfo_struct rangeinfo32;
2911+
struct comedi_rangeinfo rangeinfo;
29052912
int err;
2906-
union {
2907-
unsigned int uint;
2908-
compat_uptr_t uptr;
2909-
} temp;
2910-
2911-
rangeinfo32 = compat_ptr(arg);
2912-
rangeinfo = compat_alloc_user_space(sizeof(*rangeinfo));
29132913

2914-
/* Copy rangeinfo structure. */
2915-
if (!access_ok(rangeinfo32, sizeof(*rangeinfo32)) ||
2916-
!access_ok(rangeinfo, sizeof(*rangeinfo)))
2914+
if (copy_from_user(&rangeinfo32, compat_ptr(arg), sizeof(rangeinfo32)))
29172915
return -EFAULT;
2916+
memset(&rangeinfo, 0, sizeof(rangeinfo));
2917+
rangeinfo.range_type = rangeinfo32.range_type;
2918+
rangeinfo.range_ptr = compat_ptr(rangeinfo32.range_ptr);
29182919

2919-
err = 0;
2920-
err |= __get_user(temp.uint, &rangeinfo32->range_type);
2921-
err |= __put_user(temp.uint, &rangeinfo->range_type);
2922-
err |= __get_user(temp.uptr, &rangeinfo32->range_ptr);
2923-
err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr);
2924-
if (err)
2925-
return -EFAULT;
2926-
2927-
return comedi_unlocked_ioctl(file, COMEDI_RANGEINFO,
2928-
(unsigned long)rangeinfo);
2920+
mutex_lock(&dev->mutex);
2921+
err = do_rangeinfo_ioctl(dev, &rangeinfo);
2922+
mutex_unlock(&dev->mutex);
2923+
return err;
29292924
}
29302925

29312926
/* Copy 32-bit cmd structure to native cmd structure. */

drivers/staging/comedi/comedi_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct comedi_subdevice;
1818
struct device;
1919

2020
int do_rangeinfo_ioctl(struct comedi_device *dev,
21-
struct comedi_rangeinfo __user *arg);
21+
struct comedi_rangeinfo *it);
2222
struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device);
2323
void comedi_release_hardware_device(struct device *hardware_device);
2424
int comedi_alloc_subdevice_minor(struct comedi_subdevice *s);

drivers/staging/comedi/range.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,14 @@ EXPORT_SYMBOL_GPL(range_unknown);
4646
* array of comedi_krange structures to rangeinfo->range_ptr pointer
4747
*/
4848
int do_rangeinfo_ioctl(struct comedi_device *dev,
49-
struct comedi_rangeinfo __user *arg)
49+
struct comedi_rangeinfo *it)
5050
{
51-
struct comedi_rangeinfo it;
5251
int subd, chan;
5352
const struct comedi_lrange *lr;
5453
struct comedi_subdevice *s;
5554

56-
if (copy_from_user(&it, arg, sizeof(struct comedi_rangeinfo)))
57-
return -EFAULT;
58-
subd = (it.range_type >> 24) & 0xf;
59-
chan = (it.range_type >> 16) & 0xff;
55+
subd = (it->range_type >> 24) & 0xf;
56+
chan = (it->range_type >> 16) & 0xff;
6057

6158
if (!dev->attached)
6259
return -EINVAL;
@@ -73,15 +70,15 @@ int do_rangeinfo_ioctl(struct comedi_device *dev,
7370
return -EINVAL;
7471
}
7572

76-
if (RANGE_LENGTH(it.range_type) != lr->length) {
73+
if (RANGE_LENGTH(it->range_type) != lr->length) {
7774
dev_dbg(dev->class_dev,
7875
"wrong length %d should be %d (0x%08x)\n",
79-
RANGE_LENGTH(it.range_type),
80-
lr->length, it.range_type);
76+
RANGE_LENGTH(it->range_type),
77+
lr->length, it->range_type);
8178
return -EINVAL;
8279
}
8380

84-
if (copy_to_user(it.range_ptr, lr->range,
81+
if (copy_to_user(it->range_ptr, lr->range,
8582
sizeof(struct comedi_krange) * lr->length))
8683
return -EFAULT;
8784

0 commit comments

Comments
 (0)