diff options
author | Christian Gromm <christian.gromm@microchip.com> | 2018-05-08 11:45:15 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-08 13:41:51 +0200 |
commit | c06b99e002d06a69174a862c0da43ce0cebfe78d (patch) | |
tree | 4fd691568995722966a20b7a09230c90104842da /drivers/staging/most | |
parent | 9a32315b0b162a9ec13c41c0c69d4b93095494ca (diff) |
staging: most: usb: fix usb_disconnect race condition
The functions usb_disconnect and usb_sndbulkpipe are racing for the struct
usb_device, which might cause a null pointer dereference exception. This
patch fixes this race condition by protecting the critical section inside
the function hdm_enque with the io_mutex.
Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/most')
-rw-r--r-- | drivers/staging/most/usb/usb.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/staging/most/usb/usb.c b/drivers/staging/most/usb/usb.c index d102b08a5504..19ad61839dcf 100644 --- a/drivers/staging/most/usb/usb.c +++ b/drivers/staging/most/usb/usb.c @@ -565,14 +565,19 @@ static int hdm_enqueue(struct most_interface *iface, int channel, mdev = to_mdev(iface); conf = &mdev->conf[channel]; - dev = &mdev->usb_device->dev; - if (!mdev->usb_device) - return -ENODEV; + mutex_lock(&mdev->io_mutex); + if (!mdev->usb_device) { + retval = -ENODEV; + goto _exit; + } + dev = &mdev->usb_device->dev; urb = usb_alloc_urb(NO_ISOCHRONOUS_URB, GFP_ATOMIC); - if (!urb) - return -ENOMEM; + if (!urb) { + retval = -ENOMEM; + goto _exit; + } if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] && hdm_add_padding(mdev, channel, mbo)) { @@ -613,12 +618,14 @@ static int hdm_enqueue(struct most_interface *iface, int channel, dev_err(dev, "URB submit failed with error %d.\n", retval); goto _error_1; } - return 0; + goto _exit; _error_1: usb_unanchor_urb(urb); _error: usb_free_urb(urb); +_exit: + mutex_unlock(&mdev->io_mutex); return retval; } |