linux/drivers/staging/comedi
Ian Abbott 4b18f08be0 staging: comedi: fix a race between do_cmd_ioctl() and read/write
`do_cmd_ioctl()` is called with the comedi device's mutex locked to
process the `COMEDI_CMD` ioctl to set up comedi's asynchronous command
handling on a comedi subdevice.  `comedi_read()` and `comedi_write()`
are the `read` and `write` handlers for the comedi device, but do not
lock the mutex (for performance reasons, as some things can hold the
mutex for quite a long time).

There is a race condition if `comedi_read()` or `comedi_write()` is
running at the same time and for the same file object and comedi
subdevice as `do_cmd_ioctl()`.  `do_cmd_ioctl()` sets the subdevice's
`busy` pointer to the file object way before it sets the `SRF_RUNNING` flag
in the subdevice's `runflags` member.  `comedi_read() and
`comedi_write()` check the subdevice's `busy` pointer is pointing to the
current file object, then if the `SRF_RUNNING` flag is not set, will call
`do_become_nonbusy()` to shut down the asyncronous command.  Bad things
can happen if the asynchronous command is being shutdown and set up at
the same time.

To prevent the race, don't set the `busy` pointer until
after the `SRF_RUNNING` flag has been set.  Also, make sure the mutex is
held in `comedi_read()` and `comedi_write()` while calling
`do_become_nonbusy()` in order to avoid moving the race condition to a
point within that function.

Change some error handling `goto cleanup` statements in `do_cmd_ioctl()`
to simple `return -ERRFOO` statements as a result of changing when the
`busy` pointer is set.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2013-07-23 14:30:54 -07:00
..
drivers staging: comedi: unioxx5: use comedi_alloc_spriv() 2013-06-24 16:43:40 -07:00
kcomedilib staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
comedi_buf.c Merge 3.10-rc3 into staging-next 2013-05-27 10:54:33 +09:00
comedi_compat32.c staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
comedi_compat32.h staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
comedi_fops.c staging: comedi: fix a race between do_cmd_ioctl() and read/write 2013-07-23 14:30:54 -07:00
comedi_internal.h staging: comedi: change comedi_alloc_board_minor() to return pointer 2013-04-05 14:33:17 -07:00
comedi_pci.c staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
comedi_pcmcia.c staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
comedi_usb.c staging: comedi: introduce comedi_to_usb_dev() 2013-05-21 10:59:10 -07:00
comedi.h staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
comedidev.h staging: comedi: have comedi_set_spriv() allocate the memory 2013-06-24 15:46:56 -07:00
comedilib.h staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
drivers.c staging: comedi: drivers: let core handle freeing s->private 2013-06-17 14:31:10 -07:00
Kconfig staging: comedi: pcl730: add support for the P8R8-DIO ISA board 2013-06-08 21:57:01 -07:00
Makefile
proc.c staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
range.c staging: comedi: remove FSF address from boilerplate text 2013-05-13 17:34:22 -04:00
TODO