aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2010-05-19 13:09:50 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-06-04 16:38:53 -0400
commit53fa827e295d8b09a2446b3126577244644d256d (patch)
tree38e3ad302db84c0cad2fc714fc494f9d9fecc21f
parent4772c018e35b6a21e8a8bde54568b59998540a16 (diff)
Staging: comedi: For COMEDI_BUFINFO, check access to command
Don't allow COMEDI_BUFINFO ioctl if some other file object has locked the subdevice or has an active command. If there is no active command, just report back the last buffer position. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/comedi/comedi_fops.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 75256251250d..aeb2c00875cd 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -83,7 +83,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
83static int do_chaninfo_ioctl(struct comedi_device *dev, 83static int do_chaninfo_ioctl(struct comedi_device *dev,
84 struct comedi_chaninfo __user *arg); 84 struct comedi_chaninfo __user *arg);
85static int do_bufinfo_ioctl(struct comedi_device *dev, 85static int do_bufinfo_ioctl(struct comedi_device *dev,
86 struct comedi_bufinfo __user *arg); 86 struct comedi_bufinfo __user *arg, void *file);
87static int do_cmd_ioctl(struct comedi_device *dev, 87static int do_cmd_ioctl(struct comedi_device *dev,
88 struct comedi_cmd __user *arg, void *file); 88 struct comedi_cmd __user *arg, void *file);
89static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, 89static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg,
@@ -169,7 +169,8 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
169 break; 169 break;
170 case COMEDI_BUFINFO: 170 case COMEDI_BUFINFO:
171 rc = do_bufinfo_ioctl(dev, 171 rc = do_bufinfo_ioctl(dev,
172 (struct comedi_bufinfo __user *)arg); 172 (struct comedi_bufinfo __user *)arg,
173 file);
173 break; 174 break;
174 case COMEDI_LOCK: 175 case COMEDI_LOCK:
175 rc = do_lock_ioctl(dev, arg, file); 176 rc = do_lock_ioctl(dev, arg, file);
@@ -563,7 +564,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
563 564
564 */ 565 */
565static int do_bufinfo_ioctl(struct comedi_device *dev, 566static int do_bufinfo_ioctl(struct comedi_device *dev,
566 struct comedi_bufinfo __user *arg) 567 struct comedi_bufinfo __user *arg, void *file)
567{ 568{
568 struct comedi_bufinfo bi; 569 struct comedi_bufinfo bi;
569 struct comedi_subdevice *s; 570 struct comedi_subdevice *s;
@@ -576,6 +577,10 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
576 return -EINVAL; 577 return -EINVAL;
577 578
578 s = dev->subdevices + bi.subdevice; 579 s = dev->subdevices + bi.subdevice;
580
581 if (s->lock && s->lock != file)
582 return -EACCES;
583
579 async = s->async; 584 async = s->async;
580 585
581 if (!async) { 586 if (!async) {
@@ -588,6 +593,13 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
588 bi.bytes_written = 0; 593 bi.bytes_written = 0;
589 goto copyback; 594 goto copyback;
590 } 595 }
596 if (!s->busy) {
597 bi.bytes_read = 0;
598 bi.bytes_written = 0;
599 goto copyback_position;
600 }
601 if (s->busy != file)
602 return -EACCES;
591 603
592 if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) { 604 if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) {
593 bi.bytes_read = comedi_buf_read_alloc(async, bi.bytes_read); 605 bi.bytes_read = comedi_buf_read_alloc(async, bi.bytes_read);
@@ -606,6 +618,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev,
606 comedi_buf_write_free(async, bi.bytes_written); 618 comedi_buf_write_free(async, bi.bytes_written);
607 } 619 }
608 620
621copyback_position:
609 bi.buf_write_count = async->buf_write_count; 622 bi.buf_write_count = async->buf_write_count;
610 bi.buf_write_ptr = async->buf_write_ptr; 623 bi.buf_write_ptr = async->buf_write_ptr;
611 bi.buf_read_count = async->buf_read_count; 624 bi.buf_read_count = async->buf_read_count;