aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/option.c
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2012-10-25 09:42:40 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-25 12:39:37 -0400
commitc2dd4a8eac7821fed2c2d19e4607d0986b53b0fe (patch)
tree024fff0604ac13320f4d5db1955d406d73448e26 /drivers/usb/serial/option.c
parenta997448c89905b80aa4022f734f03685e733d711 (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/usb/serial/option.c')
-rw-r--r--drivers/usb/serial/option.c21
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 */
48static int option_probe(struct usb_serial *serial, 48static int option_probe(struct usb_serial *serial,
49 const struct usb_device_id *id); 49 const struct usb_device_id *id);
50static int option_attach(struct usb_serial *serial);
50static void option_release(struct usb_serial *serial); 51static void option_release(struct usb_serial *serial);
51static int option_send_setup(struct usb_serial_port *port); 52static int option_send_setup(struct usb_serial_port *port);
52static void option_instat_callback(struct urb *urb); 53static 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,
1335static int option_probe(struct usb_serial *serial, 1337static 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
1383static 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