USB: sierra: fix AA deadlock in open error path
authorJohan Hovold <jhovold@gmail.com>
Mon, 26 May 2014 17:22:50 +0000 (19:22 +0200)
committerBen Hutchings <ben@decadent.org.uk>
Fri, 11 Jul 2014 12:33:38 +0000 (13:33 +0100)
commit 353fe198602e8b4d1c7bdcceb8e60955087201b1 upstream.

Fix AA deadlock in open error path that would call close() and try to
grab the already held disc_mutex.

Fixes: b9a44bc19f48 ("sierra: driver urb handling improvements")

Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/usb/serial/sierra.c

index dbdfeb4..8d3edaa 100644 (file)
@@ -868,14 +868,9 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
                        usb_sndbulkpipe(serial->dev, endpoint) | USB_DIR_IN);
 
        err = sierra_submit_rx_urbs(port, GFP_KERNEL);
-       if (err) {
-               /* get rid of everything as in close */
-               sierra_close(port);
-               /* restore balance for autopm */
-               if (!serial->disconnected)
-                       usb_autopm_put_interface(serial->interface);
-               return err;
-       }
+       if (err)
+               goto err_submit;
+
        sierra_send_setup(port);
 
        serial->interface->needs_remote_wakeup = 1;
@@ -885,6 +880,16 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
        usb_autopm_put_interface(serial->interface);
 
        return 0;
+
+err_submit:
+       sierra_stop_rx_urbs(port);
+
+       for (i = 0; i < portdata->num_in_urbs; i++) {
+               sierra_release_urb(portdata->in_urbs[i]);
+               portdata->in_urbs[i] = NULL;
+       }
+
+       return err;
 }