diff options
author | Ian Abbott <abbotti@mev.co.uk> | 2010-05-19 13:09:50 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-06-04 16:38:53 -0400 |
commit | 53fa827e295d8b09a2446b3126577244644d256d (patch) | |
tree | 38e3ad302db84c0cad2fc714fc494f9d9fecc21f | |
parent | 4772c018e35b6a21e8a8bde54568b59998540a16 (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.c | 19 |
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, | |||
83 | static int do_chaninfo_ioctl(struct comedi_device *dev, | 83 | static int do_chaninfo_ioctl(struct comedi_device *dev, |
84 | struct comedi_chaninfo __user *arg); | 84 | struct comedi_chaninfo __user *arg); |
85 | static int do_bufinfo_ioctl(struct comedi_device *dev, | 85 | static int do_bufinfo_ioctl(struct comedi_device *dev, |
86 | struct comedi_bufinfo __user *arg); | 86 | struct comedi_bufinfo __user *arg, void *file); |
87 | static int do_cmd_ioctl(struct comedi_device *dev, | 87 | static int do_cmd_ioctl(struct comedi_device *dev, |
88 | struct comedi_cmd __user *arg, void *file); | 88 | struct comedi_cmd __user *arg, void *file); |
89 | static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, | 89 | static 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 | */ |
565 | static int do_bufinfo_ioctl(struct comedi_device *dev, | 566 | static 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 | ||
621 | copyback_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; |