]>
Commit | Line | Data |
---|---|---|
01079017 GKH |
1 | From db5c8b524444d4fc6b1f32d368a50a3729e50002 Mon Sep 17 00:00:00 2001 |
2 | From: Alan Stern <stern@rowland.harvard.edu> | |
3 | Date: Wed, 10 Oct 2012 14:10:21 -0400 | |
4 | Subject: USB: fix port probing and removal in garmin_gps | |
5 | ||
6 | From: Alan Stern <stern@rowland.harvard.edu> | |
7 | ||
8 | commit db5c8b524444d4fc6b1f32d368a50a3729e50002 upstream. | |
9 | ||
10 | This patch (as1615) fixes a bug in the Garmin USB serial driver. It | |
11 | uses attach, disconnect, and release routines to carry out actions | |
12 | that should be handled by port_probe and port_remove routines, because | |
13 | they access port-specific data. | |
14 | ||
15 | The bug causes an oops when the device in unplugged, because the | |
16 | private data for each port structure now gets erased when the port is | |
17 | unbound from the driver, resulting in a null-pointer dereference. | |
18 | ||
19 | Signed-off-by: Alan Stern <stern@rowland.harvard.edu> | |
20 | Reported--by: Markus Schauler <mschauler@gmail.com> | |
21 | Tested-by: Markus Schauler <mschauler@gmail.com> | |
22 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
23 | ||
24 | --- | |
25 | drivers/usb/serial/garmin_gps.c | 24 +++++++----------------- | |
26 | 1 file changed, 7 insertions(+), 17 deletions(-) | |
27 | ||
28 | --- a/drivers/usb/serial/garmin_gps.c | |
29 | +++ b/drivers/usb/serial/garmin_gps.c | |
30 | @@ -1414,11 +1414,10 @@ static void timeout_handler(unsigned lon | |
31 | ||
32 | ||
33 | ||
34 | -static int garmin_attach(struct usb_serial *serial) | |
35 | +static int garmin_port_probe(struct usb_serial_port *port) | |
36 | { | |
37 | - int status = 0; | |
38 | - struct usb_serial_port *port = serial->port[0]; | |
39 | - struct garmin_data *garmin_data_p = NULL; | |
40 | + int status; | |
41 | + struct garmin_data *garmin_data_p; | |
42 | ||
43 | garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); | |
44 | if (garmin_data_p == NULL) { | |
45 | @@ -1443,22 +1442,14 @@ static int garmin_attach(struct usb_seri | |
46 | } | |
47 | ||
48 | ||
49 | -static void garmin_disconnect(struct usb_serial *serial) | |
50 | +static int garmin_port_remove(struct usb_serial_port *port) | |
51 | { | |
52 | - struct usb_serial_port *port = serial->port[0]; | |
53 | struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | |
54 | ||
55 | usb_kill_urb(port->interrupt_in_urb); | |
56 | del_timer_sync(&garmin_data_p->timer); | |
57 | -} | |
58 | - | |
59 | - | |
60 | -static void garmin_release(struct usb_serial *serial) | |
61 | -{ | |
62 | - struct usb_serial_port *port = serial->port[0]; | |
63 | - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); | |
64 | - | |
65 | kfree(garmin_data_p); | |
66 | + return 0; | |
67 | } | |
68 | ||
69 | ||
70 | @@ -1475,9 +1466,8 @@ static struct usb_serial_driver garmin_d | |
71 | .close = garmin_close, | |
72 | .throttle = garmin_throttle, | |
73 | .unthrottle = garmin_unthrottle, | |
74 | - .attach = garmin_attach, | |
75 | - .disconnect = garmin_disconnect, | |
76 | - .release = garmin_release, | |
77 | + .port_probe = garmin_port_probe, | |
78 | + .port_remove = garmin_port_remove, | |
79 | .write = garmin_write, | |
80 | .write_room = garmin_write_room, | |
81 | .write_bulk_callback = garmin_write_bulk_callback, |