aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH Hartley Sweeten <hartleys@visionengravers.com>2012-09-18 14:43:52 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-19 04:36:45 -0400
commit95bc359f98a077a5cfc34feb0a333d11a4124b1c (patch)
tree33a0db6ef152518165b1944dd9675ed8fd266341
parentf8348677b1fffff801d5323db7ccadfdb2b290d0 (diff)
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: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Ian Abbott <abbotti@mev.co.uk> Acked-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/comedi/comedi_fops.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index df627c8223d..626fa723f19 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1137,14 +1137,14 @@ static int do_cmd_ioctl(struct comedi_device *dev,
1137 struct comedi_subdevice *s; 1137 struct comedi_subdevice *s;
1138 struct comedi_async *async; 1138 struct comedi_async *async;
1139 int ret = 0; 1139 int ret = 0;
1140 unsigned int __user *chanlist_saver = NULL; 1140 unsigned int __user *user_chanlist;
1141 1141
1142 if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) { 1142 if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) {
1143 DPRINTK("bad cmd address\n"); 1143 DPRINTK("bad cmd address\n");
1144 return -EFAULT; 1144 return -EFAULT;
1145 } 1145 }
1146 /* save user's chanlist pointer so it can be restored later */ 1146 /* save user's chanlist pointer so it can be restored later */
1147 chanlist_saver = cmd.chanlist; 1147 user_chanlist = (unsigned int __user *)cmd.chanlist;
1148 1148
1149 if (cmd.subdev >= dev->n_subdevices) { 1149 if (cmd.subdev >= dev->n_subdevices) {
1150 DPRINTK("%d no such subdevice\n", cmd.subdev); 1150 DPRINTK("%d no such subdevice\n", cmd.subdev);
@@ -1206,7 +1206,7 @@ static int do_cmd_ioctl(struct comedi_device *dev,
1206 goto cleanup; 1206 goto cleanup;
1207 } 1207 }
1208 1208
1209 if (copy_from_user(async->cmd.chanlist, cmd.chanlist, 1209 if (copy_from_user(async->cmd.chanlist, user_chanlist,
1210 async->cmd.chanlist_len * sizeof(int))) { 1210 async->cmd.chanlist_len * sizeof(int))) {
1211 DPRINTK("fault reading chanlist\n"); 1211 DPRINTK("fault reading chanlist\n");
1212 ret = -EFAULT; 1212 ret = -EFAULT;
@@ -1228,7 +1228,7 @@ static int do_cmd_ioctl(struct comedi_device *dev,
1228 DPRINTK("test returned %d\n", ret); 1228 DPRINTK("test returned %d\n", ret);
1229 cmd = async->cmd; 1229 cmd = async->cmd;
1230 /* restore chanlist pointer before copying back */ 1230 /* restore chanlist pointer before copying back */
1231 cmd.chanlist = chanlist_saver; 1231 cmd.chanlist = (unsigned int __force *)user_chanlist;
1232 cmd.data = NULL; 1232 cmd.data = NULL;
1233 if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) { 1233 if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) {
1234 DPRINTK("fault writing cmd\n"); 1234 DPRINTK("fault writing cmd\n");
@@ -1287,14 +1287,14 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
1287 struct comedi_subdevice *s; 1287 struct comedi_subdevice *s;
1288 int ret = 0; 1288 int ret = 0;
1289 unsigned int *chanlist = NULL; 1289 unsigned int *chanlist = NULL;
1290 unsigned int __user *chanlist_saver = NULL; 1290 unsigned int __user *user_chanlist;
1291 1291
1292 if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) { 1292 if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) {
1293 DPRINTK("bad cmd address\n"); 1293 DPRINTK("bad cmd address\n");
1294 return -EFAULT; 1294 return -EFAULT;
1295 } 1295 }
1296 /* save user's chanlist pointer so it can be restored later */ 1296 /* save user's chanlist pointer so it can be restored later */
1297 chanlist_saver = cmd.chanlist; 1297 user_chanlist = (unsigned int __user *)cmd.chanlist;
1298 1298
1299 if (cmd.subdev >= dev->n_subdevices) { 1299 if (cmd.subdev >= dev->n_subdevices) {
1300 DPRINTK("%d no such subdevice\n", cmd.subdev); 1300 DPRINTK("%d no such subdevice\n", cmd.subdev);
@@ -1331,7 +1331,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
1331 goto cleanup; 1331 goto cleanup;
1332 } 1332 }
1333 1333
1334 if (copy_from_user(chanlist, cmd.chanlist, 1334 if (copy_from_user(chanlist, user_chanlist,
1335 cmd.chanlist_len * sizeof(int))) { 1335 cmd.chanlist_len * sizeof(int))) {
1336 DPRINTK("fault reading chanlist\n"); 1336 DPRINTK("fault reading chanlist\n");
1337 ret = -EFAULT; 1337 ret = -EFAULT;
@@ -1351,7 +1351,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
1351 ret = s->do_cmdtest(dev, s, &cmd); 1351 ret = s->do_cmdtest(dev, s, &cmd);
1352 1352
1353 /* restore chanlist pointer before copying back */ 1353 /* restore chanlist pointer before copying back */
1354 cmd.chanlist = chanlist_saver; 1354 cmd.chanlist = (unsigned int __force *)user_chanlist;
1355 1355
1356 if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) { 1356 if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) {
1357 DPRINTK("bad cmd address\n"); 1357 DPRINTK("bad cmd address\n");