Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95bc359f authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: comedi_fops: cast the cmd->chanlist to the correct address space



Rename 'chanlist_saver' to 'user_chanlist' to avoid confusion that
it's actually a __user *.

The chanlist pointer in comedi_cmd is still a user space pointer when
the comedi_cmd is copied with copy_from_user() in do_cmd_ioctl() and
do_cmdtest_ioctl(). This pointer needs to be cast when it is saved in
user_chanlist in order to preserve its address space.

The copy_from_user() call to copy the chanlist to the kernel space
comedi_command requires the second parameter to be a __user pointer.
Use the correctly cast user_chanlist instead of cmd->chanlist.

Before the comedi_cmd is copied back to user space, the saved
user_chanlist pointer is restored. Cast the user_chanlist again so
that the address space matches the comedi_cmd.

Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Acked-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f8348677
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -1137,14 +1137,14 @@ static int do_cmd_ioctl(struct comedi_device *dev,
	struct comedi_subdevice *s;
	struct comedi_async *async;
	int ret = 0;
	unsigned int __user *chanlist_saver = NULL;
	unsigned int __user *user_chanlist;

	if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) {
		DPRINTK("bad cmd address\n");
		return -EFAULT;
	}
	/* save user's chanlist pointer so it can be restored later */
	chanlist_saver = cmd.chanlist;
	user_chanlist = (unsigned int __user *)cmd.chanlist;

	if (cmd.subdev >= dev->n_subdevices) {
		DPRINTK("%d no such subdevice\n", cmd.subdev);
@@ -1206,7 +1206,7 @@ static int do_cmd_ioctl(struct comedi_device *dev,
		goto cleanup;
	}

	if (copy_from_user(async->cmd.chanlist, cmd.chanlist,
	if (copy_from_user(async->cmd.chanlist, user_chanlist,
			   async->cmd.chanlist_len * sizeof(int))) {
		DPRINTK("fault reading chanlist\n");
		ret = -EFAULT;
@@ -1228,7 +1228,7 @@ static int do_cmd_ioctl(struct comedi_device *dev,
		DPRINTK("test returned %d\n", ret);
		cmd = async->cmd;
		/* restore chanlist pointer before copying back */
		cmd.chanlist = chanlist_saver;
		cmd.chanlist = (unsigned int __force *)user_chanlist;
		cmd.data = NULL;
		if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) {
			DPRINTK("fault writing cmd\n");
@@ -1287,14 +1287,14 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
	struct comedi_subdevice *s;
	int ret = 0;
	unsigned int *chanlist = NULL;
	unsigned int __user *chanlist_saver = NULL;
	unsigned int __user *user_chanlist;

	if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) {
		DPRINTK("bad cmd address\n");
		return -EFAULT;
	}
	/* save user's chanlist pointer so it can be restored later */
	chanlist_saver = cmd.chanlist;
	user_chanlist = (unsigned int __user *)cmd.chanlist;

	if (cmd.subdev >= dev->n_subdevices) {
		DPRINTK("%d no such subdevice\n", cmd.subdev);
@@ -1331,7 +1331,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
			goto cleanup;
		}

		if (copy_from_user(chanlist, cmd.chanlist,
		if (copy_from_user(chanlist, user_chanlist,
				   cmd.chanlist_len * sizeof(int))) {
			DPRINTK("fault reading chanlist\n");
			ret = -EFAULT;
@@ -1351,7 +1351,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
	ret = s->do_cmdtest(dev, s, &cmd);

	/* restore chanlist pointer before copying back */
	cmd.chanlist = chanlist_saver;
	cmd.chanlist = (unsigned int __force *)user_chanlist;

	if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) {
		DPRINTK("bad cmd address\n");