diff options
author | Johan Hovold <jhovold@gmail.com> | 2012-10-25 09:42:40 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-25 12:39:37 -0400 |
commit | c2dd4a8eac7821fed2c2d19e4607d0986b53b0fe (patch) | |
tree | 024fff0604ac13320f4d5db1955d406d73448e26 /drivers | |
parent | a997448c89905b80aa4022f734f03685e733d711 (diff) |
USB: option: fix interface-data memory leak in error path
Move interface data allocation to attach so that it is deallocated
should usb-serial probe fail.
Note that the usb device id is stored at probe so that it can be used
in attach to determine send-setup blacklisting.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/serial/option.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index eb4bdd4a0106..5dee7d61241e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -47,6 +47,7 @@ | |||
47 | /* Function prototypes */ | 47 | /* Function prototypes */ |
48 | static int option_probe(struct usb_serial *serial, | 48 | static int option_probe(struct usb_serial *serial, |
49 | const struct usb_device_id *id); | 49 | const struct usb_device_id *id); |
50 | static int option_attach(struct usb_serial *serial); | ||
50 | static void option_release(struct usb_serial *serial); | 51 | static void option_release(struct usb_serial *serial); |
51 | static int option_send_setup(struct usb_serial_port *port); | 52 | static int option_send_setup(struct usb_serial_port *port); |
52 | static void option_instat_callback(struct urb *urb); | 53 | static void option_instat_callback(struct urb *urb); |
@@ -1288,6 +1289,7 @@ static struct usb_serial_driver option_1port_device = { | |||
1288 | .tiocmget = usb_wwan_tiocmget, | 1289 | .tiocmget = usb_wwan_tiocmget, |
1289 | .tiocmset = usb_wwan_tiocmset, | 1290 | .tiocmset = usb_wwan_tiocmset, |
1290 | .ioctl = usb_wwan_ioctl, | 1291 | .ioctl = usb_wwan_ioctl, |
1292 | .attach = option_attach, | ||
1291 | .release = option_release, | 1293 | .release = option_release, |
1292 | .port_probe = usb_wwan_port_probe, | 1294 | .port_probe = usb_wwan_port_probe, |
1293 | .port_remove = usb_wwan_port_remove, | 1295 | .port_remove = usb_wwan_port_remove, |
@@ -1335,8 +1337,6 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, | |||
1335 | static int option_probe(struct usb_serial *serial, | 1337 | static int option_probe(struct usb_serial *serial, |
1336 | const struct usb_device_id *id) | 1338 | const struct usb_device_id *id) |
1337 | { | 1339 | { |
1338 | struct usb_wwan_intf_private *data; | ||
1339 | struct option_private *priv; | ||
1340 | struct usb_interface_descriptor *iface_desc = | 1340 | struct usb_interface_descriptor *iface_desc = |
1341 | &serial->interface->cur_altsetting->desc; | 1341 | &serial->interface->cur_altsetting->desc; |
1342 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; | 1342 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; |
@@ -1374,6 +1374,19 @@ static int option_probe(struct usb_serial *serial, | |||
1374 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) | 1374 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) |
1375 | return -ENODEV; | 1375 | return -ENODEV; |
1376 | 1376 | ||
1377 | /* Store device id so we can use it during attach. */ | ||
1378 | usb_set_serial_data(serial, (void *)id); | ||
1379 | |||
1380 | return 0; | ||
1381 | } | ||
1382 | |||
1383 | static int option_attach(struct usb_serial *serial) | ||
1384 | { | ||
1385 | struct usb_interface_descriptor *iface_desc; | ||
1386 | const struct usb_device_id *id; | ||
1387 | struct usb_wwan_intf_private *data; | ||
1388 | struct option_private *priv; | ||
1389 | |||
1377 | data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); | 1390 | data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); |
1378 | if (!data) | 1391 | if (!data) |
1379 | return -ENOMEM; | 1392 | return -ENOMEM; |
@@ -1384,6 +1397,10 @@ static int option_probe(struct usb_serial *serial, | |||
1384 | return -ENOMEM; | 1397 | return -ENOMEM; |
1385 | } | 1398 | } |
1386 | 1399 | ||
1400 | /* Retrieve device id stored at probe. */ | ||
1401 | id = usb_get_serial_data(serial); | ||
1402 | iface_desc = &serial->interface->cur_altsetting->desc; | ||
1403 | |||
1387 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; | 1404 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; |
1388 | data->private = priv; | 1405 | data->private = priv; |
1389 | 1406 | ||