Skip to content

Commit bac42fb

Browse files
author
Al Viro
committed
comedi: get rid of compat_alloc_user_space() mess in COMEDI_CMD{,TEST} compat
Signed-off-by: Al Viro <[email protected]>
1 parent 0a3ccc7 commit bac42fb

File tree

1 file changed

+66
-115
lines changed

1 file changed

+66
-115
lines changed

drivers/staging/comedi/comedi_fops.c

Lines changed: 66 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2931,155 +2931,106 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
29312931
}
29322932

29332933
/* Copy 32-bit cmd structure to native cmd structure. */
2934-
static int get_compat_cmd(struct comedi_cmd __user *cmd,
2934+
static int get_compat_cmd(struct comedi_cmd *cmd,
29352935
struct comedi32_cmd_struct __user *cmd32)
29362936
{
2937-
int err;
2938-
union {
2939-
unsigned int uint;
2940-
compat_uptr_t uptr;
2941-
} temp;
2942-
2943-
/* Copy cmd structure. */
2944-
if (!access_ok(cmd32, sizeof(*cmd32)) ||
2945-
!access_ok(cmd, sizeof(*cmd)))
2937+
struct comedi32_cmd_struct v32;
2938+
2939+
if (copy_from_user(&v32, cmd32, sizeof(v32)))
29462940
return -EFAULT;
29472941

2948-
err = 0;
2949-
err |= __get_user(temp.uint, &cmd32->subdev);
2950-
err |= __put_user(temp.uint, &cmd->subdev);
2951-
err |= __get_user(temp.uint, &cmd32->flags);
2952-
err |= __put_user(temp.uint, &cmd->flags);
2953-
err |= __get_user(temp.uint, &cmd32->start_src);
2954-
err |= __put_user(temp.uint, &cmd->start_src);
2955-
err |= __get_user(temp.uint, &cmd32->start_arg);
2956-
err |= __put_user(temp.uint, &cmd->start_arg);
2957-
err |= __get_user(temp.uint, &cmd32->scan_begin_src);
2958-
err |= __put_user(temp.uint, &cmd->scan_begin_src);
2959-
err |= __get_user(temp.uint, &cmd32->scan_begin_arg);
2960-
err |= __put_user(temp.uint, &cmd->scan_begin_arg);
2961-
err |= __get_user(temp.uint, &cmd32->convert_src);
2962-
err |= __put_user(temp.uint, &cmd->convert_src);
2963-
err |= __get_user(temp.uint, &cmd32->convert_arg);
2964-
err |= __put_user(temp.uint, &cmd->convert_arg);
2965-
err |= __get_user(temp.uint, &cmd32->scan_end_src);
2966-
err |= __put_user(temp.uint, &cmd->scan_end_src);
2967-
err |= __get_user(temp.uint, &cmd32->scan_end_arg);
2968-
err |= __put_user(temp.uint, &cmd->scan_end_arg);
2969-
err |= __get_user(temp.uint, &cmd32->stop_src);
2970-
err |= __put_user(temp.uint, &cmd->stop_src);
2971-
err |= __get_user(temp.uint, &cmd32->stop_arg);
2972-
err |= __put_user(temp.uint, &cmd->stop_arg);
2973-
err |= __get_user(temp.uptr, &cmd32->chanlist);
2974-
err |= __put_user((unsigned int __force *)compat_ptr(temp.uptr),
2975-
&cmd->chanlist);
2976-
err |= __get_user(temp.uint, &cmd32->chanlist_len);
2977-
err |= __put_user(temp.uint, &cmd->chanlist_len);
2978-
err |= __get_user(temp.uptr, &cmd32->data);
2979-
err |= __put_user(compat_ptr(temp.uptr), &cmd->data);
2980-
err |= __get_user(temp.uint, &cmd32->data_len);
2981-
err |= __put_user(temp.uint, &cmd->data_len);
2982-
return err ? -EFAULT : 0;
2942+
cmd->subdev = v32.subdev;
2943+
cmd->flags = v32.flags;
2944+
cmd->start_src = v32.start_src;
2945+
cmd->start_arg = v32.start_arg;
2946+
cmd->scan_begin_src = v32.scan_begin_src;
2947+
cmd->scan_begin_arg = v32.scan_begin_arg;
2948+
cmd->convert_src = v32.convert_src;
2949+
cmd->convert_arg = v32.convert_arg;
2950+
cmd->scan_end_src = v32.scan_end_src;
2951+
cmd->scan_end_arg = v32.scan_end_arg;
2952+
cmd->stop_src = v32.stop_src;
2953+
cmd->stop_arg = v32.stop_arg;
2954+
cmd->chanlist = compat_ptr(v32.chanlist);
2955+
cmd->chanlist_len = v32.chanlist_len;
2956+
cmd->data = compat_ptr(v32.data);
2957+
cmd->data_len = v32.data_len;
2958+
return 0;
29832959
}
29842960

29852961
/* Copy native cmd structure to 32-bit cmd structure. */
29862962
static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32,
2987-
struct comedi_cmd __user *cmd)
2988-
{
2989-
int err;
2990-
unsigned int temp;
2991-
2992-
/*
2993-
* Copy back most of cmd structure.
2994-
*
2995-
* Assume the pointer values are already valid.
2996-
* (Could use ptr_to_compat() to set them.)
2997-
*/
2998-
if (!access_ok(cmd, sizeof(*cmd)) ||
2999-
!access_ok(cmd32, sizeof(*cmd32)))
3000-
return -EFAULT;
3001-
3002-
err = 0;
3003-
err |= __get_user(temp, &cmd->subdev);
3004-
err |= __put_user(temp, &cmd32->subdev);
3005-
err |= __get_user(temp, &cmd->flags);
3006-
err |= __put_user(temp, &cmd32->flags);
3007-
err |= __get_user(temp, &cmd->start_src);
3008-
err |= __put_user(temp, &cmd32->start_src);
3009-
err |= __get_user(temp, &cmd->start_arg);
3010-
err |= __put_user(temp, &cmd32->start_arg);
3011-
err |= __get_user(temp, &cmd->scan_begin_src);
3012-
err |= __put_user(temp, &cmd32->scan_begin_src);
3013-
err |= __get_user(temp, &cmd->scan_begin_arg);
3014-
err |= __put_user(temp, &cmd32->scan_begin_arg);
3015-
err |= __get_user(temp, &cmd->convert_src);
3016-
err |= __put_user(temp, &cmd32->convert_src);
3017-
err |= __get_user(temp, &cmd->convert_arg);
3018-
err |= __put_user(temp, &cmd32->convert_arg);
3019-
err |= __get_user(temp, &cmd->scan_end_src);
3020-
err |= __put_user(temp, &cmd32->scan_end_src);
3021-
err |= __get_user(temp, &cmd->scan_end_arg);
3022-
err |= __put_user(temp, &cmd32->scan_end_arg);
3023-
err |= __get_user(temp, &cmd->stop_src);
3024-
err |= __put_user(temp, &cmd32->stop_src);
3025-
err |= __get_user(temp, &cmd->stop_arg);
3026-
err |= __put_user(temp, &cmd32->stop_arg);
2963+
struct comedi_cmd *cmd)
2964+
{
2965+
struct comedi32_cmd_struct v32;
2966+
2967+
memset(&v32, 0, sizeof(v32));
2968+
v32.subdev = cmd->subdev;
2969+
v32.flags = cmd->flags;
2970+
v32.start_src = cmd->start_src;
2971+
v32.start_arg = cmd->start_arg;
2972+
v32.scan_begin_src = cmd->scan_begin_src;
2973+
v32.scan_begin_arg = cmd->scan_begin_arg;
2974+
v32.convert_src = cmd->convert_src;
2975+
v32.convert_arg = cmd->convert_arg;
2976+
v32.scan_end_src = cmd->scan_end_src;
2977+
v32.scan_end_arg = cmd->scan_end_arg;
2978+
v32.stop_src = cmd->stop_src;
2979+
v32.stop_arg = cmd->stop_arg;
30272980
/* Assume chanlist pointer is unchanged. */
3028-
err |= __get_user(temp, &cmd->chanlist_len);
3029-
err |= __put_user(temp, &cmd32->chanlist_len);
3030-
/* Assume data pointer is unchanged. */
3031-
err |= __get_user(temp, &cmd->data_len);
3032-
err |= __put_user(temp, &cmd32->data_len);
3033-
return err ? -EFAULT : 0;
2981+
v32.chanlist = ptr_to_compat(cmd->chanlist);
2982+
v32.chanlist_len = cmd->chanlist_len;
2983+
v32.data = ptr_to_compat(cmd->data);
2984+
v32.data_len = cmd->data_len;
2985+
return copy_to_user(cmd32, &v32, sizeof(v32));
30342986
}
30352987

30362988
/* Handle 32-bit COMEDI_CMD ioctl. */
30372989
static int compat_cmd(struct file *file, unsigned long arg)
30382990
{
3039-
struct comedi_cmd __user *cmd;
3040-
struct comedi32_cmd_struct __user *cmd32;
2991+
struct comedi_file *cfp = file->private_data;
2992+
struct comedi_device *dev = cfp->dev;
2993+
struct comedi_cmd cmd;
2994+
bool copy = false;
30412995
int rc, err;
30422996

3043-
cmd32 = compat_ptr(arg);
3044-
cmd = compat_alloc_user_space(sizeof(*cmd));
3045-
3046-
rc = get_compat_cmd(cmd, cmd32);
2997+
rc = get_compat_cmd(&cmd, compat_ptr(arg));
30472998
if (rc)
30482999
return rc;
30493000

3050-
rc = comedi_unlocked_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
3051-
if (rc == -EAGAIN) {
3001+
mutex_lock(&dev->mutex);
3002+
rc = do_cmd_ioctl(dev, &cmd, &copy, file);
3003+
mutex_unlock(&dev->mutex);
3004+
if (copy) {
30523005
/* Special case: copy cmd back to user. */
3053-
err = put_compat_cmd(cmd32, cmd);
3006+
err = put_compat_cmd(compat_ptr(arg), &cmd);
30543007
if (err)
30553008
rc = err;
30563009
}
3057-
30583010
return rc;
30593011
}
30603012

30613013
/* Handle 32-bit COMEDI_CMDTEST ioctl. */
30623014
static int compat_cmdtest(struct file *file, unsigned long arg)
30633015
{
3064-
struct comedi_cmd __user *cmd;
3065-
struct comedi32_cmd_struct __user *cmd32;
3016+
struct comedi_file *cfp = file->private_data;
3017+
struct comedi_device *dev = cfp->dev;
3018+
struct comedi_cmd cmd;
3019+
bool copy = false;
30663020
int rc, err;
30673021

3068-
cmd32 = compat_ptr(arg);
3069-
cmd = compat_alloc_user_space(sizeof(*cmd));
3070-
3071-
rc = get_compat_cmd(cmd, cmd32);
3022+
rc = get_compat_cmd(&cmd, compat_ptr(arg));
30723023
if (rc)
30733024
return rc;
30743025

3075-
rc = comedi_unlocked_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd);
3076-
if (rc < 0)
3077-
return rc;
3078-
3079-
err = put_compat_cmd(cmd32, cmd);
3080-
if (err)
3081-
rc = err;
3082-
3026+
mutex_lock(&dev->mutex);
3027+
rc = do_cmdtest_ioctl(dev, &cmd, &copy, file);
3028+
mutex_unlock(&dev->mutex);
3029+
if (copy) {
3030+
err = put_compat_cmd(compat_ptr(arg), &cmd);
3031+
if (err)
3032+
rc = err;
3033+
}
30833034
return rc;
30843035
}
30853036

0 commit comments

Comments
 (0)