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>
This commit is contained in:
@@ -1886,24 +1886,22 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
|
||||
{
|
||||
struct ftdi_private *priv = usb_get_serial_port_data(port);
|
||||
|
||||
mutex_lock(&port->serial->disc_mutex);
|
||||
if (!port->serial->disconnected) {
|
||||
/* Disable flow control */
|
||||
if (!on && usb_control_msg(port->serial->dev,
|
||||
/* Disable flow control */
|
||||
if (!on) {
|
||||
if (usb_control_msg(port->serial->dev,
|
||||
usb_sndctrlpipe(port->serial->dev, 0),
|
||||
FTDI_SIO_SET_FLOW_CTRL_REQUEST,
|
||||
FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
|
||||
0, priv->interface, NULL, 0,
|
||||
WDR_TIMEOUT) < 0) {
|
||||
dev_err(&port->dev, "error from flowcontrol urb\n");
|
||||
dev_err(&port->dev, "error from flowcontrol urb\n");
|
||||
}
|
||||
/* drop RTS and DTR */
|
||||
if (on)
|
||||
set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
else
|
||||
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
}
|
||||
mutex_unlock(&port->serial->disc_mutex);
|
||||
/* drop RTS and DTR */
|
||||
if (on)
|
||||
set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
else
|
||||
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user