diff options
author | H Hartley Sweeten <hartleys@visionengravers.com> | 2012-09-18 14:43:52 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-19 04:36:45 -0400 |
commit | 95bc359f98a077a5cfc34feb0a333d11a4124b1c (patch) | |
tree | 33a0db6ef152518165b1944dd9675ed8fd266341 | |
parent | f8348677b1fffff801d5323db7ccadfdb2b290d0 (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.c | 16 |
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"); |