staging: most: usb: fix usb_disconnect race condition
authorChristian Gromm <christian.gromm@microchip.com>
Tue, 8 May 2018 09:45:15 +0000 (11:45 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 May 2018 11:41:51 +0000 (13:41 +0200)
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>
drivers/staging/most/usb/usb.c

index d102b08..19ad618 100644 (file)
@@ -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;
 }