aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2012-10-10 14:10:21 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-16 13:25:55 -0400
commitdb5c8b524444d4fc6b1f32d368a50a3729e50002 (patch)
treeed09dfb961fd6c505dc292cf26335e7110db5fe3
parent8bf769eb5f6efc33f95088850f33fcc05d28b508 (diff)
USB: fix port probing and removal in garmin_gps
This patch (as1615) fixes a bug in the Garmin USB serial driver. It uses attach, disconnect, and release routines to carry out actions that should be handled by port_probe and port_remove routines, because they access port-specific data. The bug causes an oops when the device in unplugged, because the private data for each port structure now gets erased when the port is unbound from the driver, resulting in a null-pointer dereference. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Reported--by: Markus Schauler <mschauler@gmail.com> Tested-by: Markus Schauler <mschauler@gmail.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/serial/garmin_gps.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 3ee92648c02d..203358d7e7bc 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1405,11 +1405,10 @@ static void timeout_handler(unsigned long data)
1405 1405
1406 1406
1407 1407
1408static int garmin_attach(struct usb_serial *serial) 1408static int garmin_port_probe(struct usb_serial_port *port)
1409{ 1409{
1410 int status = 0; 1410 int status;
1411 struct usb_serial_port *port = serial->port[0]; 1411 struct garmin_data *garmin_data_p;
1412 struct garmin_data *garmin_data_p = NULL;
1413 1412
1414 garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); 1413 garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL);
1415 if (garmin_data_p == NULL) { 1414 if (garmin_data_p == NULL) {
@@ -1434,22 +1433,14 @@ static int garmin_attach(struct usb_serial *serial)
1434} 1433}
1435 1434
1436 1435
1437static void garmin_disconnect(struct usb_serial *serial) 1436static int garmin_port_remove(struct usb_serial_port *port)
1438{ 1437{
1439 struct usb_serial_port *port = serial->port[0];
1440 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); 1438 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
1441 1439
1442 usb_kill_urb(port->interrupt_in_urb); 1440 usb_kill_urb(port->interrupt_in_urb);
1443 del_timer_sync(&garmin_data_p->timer); 1441 del_timer_sync(&garmin_data_p->timer);
1444}
1445
1446
1447static void garmin_release(struct usb_serial *serial)
1448{
1449 struct usb_serial_port *port = serial->port[0];
1450 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
1451
1452 kfree(garmin_data_p); 1442 kfree(garmin_data_p);
1443 return 0;
1453} 1444}
1454 1445
1455 1446
@@ -1466,9 +1457,8 @@ static struct usb_serial_driver garmin_device = {
1466 .close = garmin_close, 1457 .close = garmin_close,
1467 .throttle = garmin_throttle, 1458 .throttle = garmin_throttle,
1468 .unthrottle = garmin_unthrottle, 1459 .unthrottle = garmin_unthrottle,
1469 .attach = garmin_attach, 1460 .port_probe = garmin_port_probe,
1470 .disconnect = garmin_disconnect, 1461 .port_remove = garmin_port_remove,
1471 .release = garmin_release,
1472 .write = garmin_write, 1462 .write = garmin_write,
1473 .write_room = garmin_write_room, 1463 .write_room = garmin_write_room,
1474 .write_bulk_callback = garmin_write_bulk_callback, 1464 .write_bulk_callback = garmin_write_bulk_callback,