diff options
| author | Johan Hovold <johan@kernel.org> | 2019-10-11 11:57:35 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-29 09:15:16 +0100 |
| commit | afa3bc254e0f054865f8b18d298f273e00c39849 (patch) | |
| tree | 82565d8f32d7cdf5c77201cea3e7626708d7d8ae | |
| parent | f0b1f7e0c8a7da3db9122c8368bbe34c7e8763c7 (diff) | |
| download | linux-afa3bc254e0f054865f8b18d298f273e00c39849.tar.gz linux-afa3bc254e0f054865f8b18d298f273e00c39849.tar.bz2 linux-afa3bc254e0f054865f8b18d298f273e00c39849.zip | |
USB: serial: ti_usb_3410_5052: fix port-close races
commit 6f1d1dc8d540a9aa6e39b9cb86d3a67bbc1c8d8d upstream.
Fix races between closing a port and opening or closing another port on
the same device which could lead to a failure to start or stop the
shared interrupt URB. The latter could potentially cause a
use-after-free or worse in the completion handler on driver unbind.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/usb/serial/ti_usb_3410_5052.c | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 836cb93ba49e..a7e41723c34c 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -778,7 +778,6 @@ static void ti_close(struct usb_serial_port *port) struct ti_port *tport; int port_number; int status; - int do_unlock; unsigned long flags; tdev = usb_get_serial_data(port->serial); @@ -802,16 +801,13 @@ static void ti_close(struct usb_serial_port *port) "%s - cannot send close port command, %d\n" , __func__, status); - /* if mutex_lock is interrupted, continue anyway */ - do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock); + mutex_lock(&tdev->td_open_close_lock); --tport->tp_tdev->td_open_port_count; - if (tport->tp_tdev->td_open_port_count <= 0) { + if (tport->tp_tdev->td_open_port_count == 0) { /* last port is closed, shut down interrupt urb */ usb_kill_urb(port->serial->port[0]->interrupt_in_urb); - tport->tp_tdev->td_open_port_count = 0; } - if (do_unlock) - mutex_unlock(&tdev->td_open_close_lock); + mutex_unlock(&tdev->td_open_close_lock); } |
