aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.c
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2013-02-13 11:53:28 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-02-13 12:20:06 -0500
commitb2ca699076573c94fee9a73cb0d8645383b602a0 (patch)
treeb9579ce8ed1511a5b3a234b03392b3c095de9231 /drivers/usb/serial/sierra.c
parentcd565279e51bedee1b2988e84f9b3bef485adeb6 (diff)
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 0998d0631001 ("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>
Diffstat (limited to 'drivers/usb/serial/sierra.c')
-rw-r--r--drivers/usb/serial/sierra.c8
1 files changed, 1 insertions, 7 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index af06f2f5f38b..d4426c038c32 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -861,19 +861,13 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
861 861
862static void sierra_dtr_rts(struct usb_serial_port *port, int on) 862static void sierra_dtr_rts(struct usb_serial_port *port, int on)
863{ 863{
864 struct usb_serial *serial = port->serial;
865 struct sierra_port_private *portdata; 864 struct sierra_port_private *portdata;
866 865
867 portdata = usb_get_serial_port_data(port); 866 portdata = usb_get_serial_port_data(port);
868 portdata->rts_state = on; 867 portdata->rts_state = on;
869 portdata->dtr_state = on; 868 portdata->dtr_state = on;
870 869
871 if (serial->dev) { 870 sierra_send_setup(port);
872 mutex_lock(&serial->disc_mutex);
873 if (!serial->disconnected)
874 sierra_send_setup(port);
875 mutex_unlock(&serial->disc_mutex);
876 }
877} 871}
878 872
879static int sierra_startup(struct usb_serial *serial) 873static int sierra_startup(struct usb_serial *serial)