Commit c2dd4a8e authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

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: default avatarJohan Hovold <jhovold@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a997448c
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
/* Function prototypes */ /* Function prototypes */
static int option_probe(struct usb_serial *serial, static int option_probe(struct usb_serial *serial,
const struct usb_device_id *id); const struct usb_device_id *id);
static int option_attach(struct usb_serial *serial);
static void option_release(struct usb_serial *serial); static void option_release(struct usb_serial *serial);
static int option_send_setup(struct usb_serial_port *port); static int option_send_setup(struct usb_serial_port *port);
static void option_instat_callback(struct urb *urb); static void option_instat_callback(struct urb *urb);
...@@ -1288,6 +1289,7 @@ static struct usb_serial_driver option_1port_device = { ...@@ -1288,6 +1289,7 @@ static struct usb_serial_driver option_1port_device = {
.tiocmget = usb_wwan_tiocmget, .tiocmget = usb_wwan_tiocmget,
.tiocmset = usb_wwan_tiocmset, .tiocmset = usb_wwan_tiocmset,
.ioctl = usb_wwan_ioctl, .ioctl = usb_wwan_ioctl,
.attach = option_attach,
.release = option_release, .release = option_release,
.port_probe = usb_wwan_port_probe, .port_probe = usb_wwan_port_probe,
.port_remove = usb_wwan_port_remove, .port_remove = usb_wwan_port_remove,
...@@ -1335,8 +1337,6 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, ...@@ -1335,8 +1337,6 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
static int option_probe(struct usb_serial *serial, static int option_probe(struct usb_serial *serial,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_wwan_intf_private *data;
struct option_private *priv;
struct usb_interface_descriptor *iface_desc = struct usb_interface_descriptor *iface_desc =
&serial->interface->cur_altsetting->desc; &serial->interface->cur_altsetting->desc;
struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
...@@ -1374,6 +1374,19 @@ static int option_probe(struct usb_serial *serial, ...@@ -1374,6 +1374,19 @@ static int option_probe(struct usb_serial *serial,
iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
return -ENODEV; return -ENODEV;
/* Store device id so we can use it during attach. */
usb_set_serial_data(serial, (void *)id);
return 0;
}
static int option_attach(struct usb_serial *serial)
{
struct usb_interface_descriptor *iface_desc;
const struct usb_device_id *id;
struct usb_wwan_intf_private *data;
struct option_private *priv;
data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
...@@ -1384,6 +1397,10 @@ static int option_probe(struct usb_serial *serial, ...@@ -1384,6 +1397,10 @@ static int option_probe(struct usb_serial *serial,
return -ENOMEM; return -ENOMEM;
} }
/* Retrieve device id stored at probe. */
id = usb_get_serial_data(serial);
iface_desc = &serial->interface->cur_altsetting->desc;
priv->bInterfaceNumber = iface_desc->bInterfaceNumber; priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
data->private = priv; data->private = priv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment