USB: serial: fix null-pointer dereferences on disconnect

Make sure serial-driver dtr_rts is called with disc_mutex held after
checking the disconnected flag.

Due to a bug in the tty layer, dtr_rts may get called after a device has
been disconnected and the tty-device unregistered. Some drivers have had
individual checks for disconnect to make sure the disconnected interface
was not accessed, but this should really be handled in usb-serial core
(at least until the long-standing tty-bug has been fixed).

Note that the problem has been made more acute with commit 0998d06310
("device-core: Ensure drvdata = NULL when no driver is bound") as the
port data is now also NULL when dtr_rts is called resulting in further
oopses.

Reported-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
此提交包含在:
Johan Hovold
2013-02-13 17:53:28 +01:00
提交者 Greg Kroah-Hartman
父節點 cd565279e5
當前提交 b2ca699076
共有 7 個檔案被更改,包括 50 行新增59 行删除

查看文件

@@ -506,19 +506,16 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on)
{
struct usb_device *dev = port->serial->dev;
mutex_lock(&port->serial->disc_mutex);
if (!port->serial->disconnected) {
/* Disable flow control */
if (!on &&
ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
/* Disable flow control */
if (!on) {
if (ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
dev_err(&port->dev, "error from flowcontrol urb\n");
/* drop RTS and DTR */
if (on)
set_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
else
clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
}
mutex_unlock(&port->serial->disc_mutex);
/* drop RTS and DTR */
if (on)
set_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
else
clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
}
static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)