diff options
author | Ian Abbott | 2013-11-08 16:03:42 +0100 |
---|---|---|
committer | Greg Kroah-Hartman | 2013-11-12 01:16:45 +0100 |
commit | 63ab039511509739f881acfb99aef76b772e35a2 (patch) | |
tree | 0405ce8c45c3c7c3feabd050f0f6e250e772e8e5 /drivers/staging/comedi/comedi_fops.c | |
parent | staging: comedi: remove comedi_dev_from_minor() (diff) | |
download | kernel-qcow2-linux-63ab039511509739f881acfb99aef76b772e35a2.tar.gz kernel-qcow2-linux-63ab039511509739f881acfb99aef76b772e35a2.tar.xz kernel-qcow2-linux-63ab039511509739f881acfb99aef76b772e35a2.zip |
staging: comedi: make determination of read or write subdevice safer
`comedi_read_subdevice()` and `comedi_write_subdevice()` respectively
determine the read and write subdevice to use for a comedi device,
depending on a minor device number passed in. The comedi device has a
main "board" minor device number and may also have dynamically assigned,
subdevice-specific minor device numbers, in a range of numbers shared by
all comedi devices. If the minor device number is within the range of
subdevice-specific minor device numbers, both functions call
`comedi_subdevice_from_minor()` to determine what subdevice is
associated with the minor device number (if any) and then check the
subdevice belongs to the comedi device. Since the subdevice might
belong to a different comedi device, the check is not protected against
the subdevice being freed. Perform the check in
`comedi_subdevice_from_minor()` instead, where it is protected against
the subdevice being freed. Make it return `NULL` if the subdevice does
not belong to the device.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index d569484f315b..8cb9d956e8f2 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -177,7 +177,7 @@ static void comedi_free_board_dev(struct comedi_device *dev) } static struct comedi_subdevice -*comedi_subdevice_from_minor(unsigned minor) +*comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned minor) { struct comedi_subdevice *s; unsigned int i = minor - COMEDI_NUM_BOARD_MINORS; @@ -185,6 +185,8 @@ static struct comedi_subdevice BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS); mutex_lock(&comedi_subdevice_minor_table_lock); s = comedi_subdevice_minor_table[i]; + if (s && s->device != dev) + s = NULL; mutex_unlock(&comedi_subdevice_minor_table_lock); return s; } @@ -229,10 +231,8 @@ comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) struct comedi_subdevice *s; if (minor >= COMEDI_NUM_BOARD_MINORS) { - s = comedi_subdevice_from_minor(minor); - if (!s || s->device != dev) - return NULL; - if (s->subdev_flags & SDF_CMD_READ) + s = comedi_subdevice_from_minor(dev, minor); + if (s == NULL || (s->subdev_flags & SDF_CMD_READ)) return s; } return dev->read_subdev; @@ -244,10 +244,8 @@ comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor) struct comedi_subdevice *s; if (minor >= COMEDI_NUM_BOARD_MINORS) { - s = comedi_subdevice_from_minor(minor); - if (!s || s->device != dev) - return NULL; - if (s->subdev_flags & SDF_CMD_WRITE) + s = comedi_subdevice_from_minor(dev, minor); + if (s == NULL || (s->subdev_flags & SDF_CMD_WRITE)) return s; } return dev->write_subdev; |