summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2016-05-08 20:07:56 +0200
committerJiri Slaby <jslaby@suse.cz>2016-06-15 09:32:07 +0200
commit53ad8bf0a16b3d8e31b07004250f3468d279376c (patch)
treef0dff90d91cabb8450f49f35886c05cf7c9c309b /drivers/usb
parente78a0e1d718178cbee94a5d6f9ba109833708400 (diff)
downloadlwn-53ad8bf0a16b3d8e31b07004250f3468d279376c.tar.gz
lwn-53ad8bf0a16b3d8e31b07004250f3468d279376c.zip
USB: serial: io_edgeport: fix memory leaks in attach error path
commit c5c0c55598cefc826d6cfb0a417eeaee3631715c upstream. Private data, URBs and buffers allocated for Epic devices during attach were never released on errors (e.g. missing endpoints). Fixes: 6e8cf7751f9f ("USB: add EPIC support to the io_edgeport driver") Signed-off-by: Johan Hovold <johan@kernel.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/io_edgeport.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index c91481d74a14..60bff3b75609 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -2879,14 +2879,15 @@ static int edge_startup(struct usb_serial *serial)
usb_alloc_urb(0, GFP_KERNEL);
if (!edge_serial->interrupt_read_urb) {
dev_err(ddev, "out of memory\n");
- return -ENOMEM;
+ response = -ENOMEM;
+ break;
}
edge_serial->interrupt_in_buffer =
kmalloc(buffer_size, GFP_KERNEL);
if (!edge_serial->interrupt_in_buffer) {
dev_err(ddev, "out of memory\n");
- usb_free_urb(edge_serial->interrupt_read_urb);
- return -ENOMEM;
+ response = -ENOMEM;
+ break;
}
edge_serial->interrupt_in_endpoint =
endpoint->bEndpointAddress;
@@ -2916,14 +2917,15 @@ static int edge_startup(struct usb_serial *serial)
usb_alloc_urb(0, GFP_KERNEL);
if (!edge_serial->read_urb) {
dev_err(ddev, "out of memory\n");
- return -ENOMEM;
+ response = -ENOMEM;
+ break;
}
edge_serial->bulk_in_buffer =
kmalloc(buffer_size, GFP_KERNEL);
if (!edge_serial->bulk_in_buffer) {
dev_err(&dev->dev, "out of memory\n");
- usb_free_urb(edge_serial->read_urb);
- return -ENOMEM;
+ response = -ENOMEM;
+ break;
}
edge_serial->bulk_in_endpoint =
endpoint->bEndpointAddress;
@@ -2949,9 +2951,22 @@ static int edge_startup(struct usb_serial *serial)
}
}
- if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) {
- dev_err(ddev, "Error - the proper endpoints were not found!\n");
- return -ENODEV;
+ if (response || !interrupt_in_found || !bulk_in_found ||
+ !bulk_out_found) {
+ if (!response) {
+ dev_err(ddev, "expected endpoints not found\n");
+ response = -ENODEV;
+ }
+
+ usb_free_urb(edge_serial->interrupt_read_urb);
+ kfree(edge_serial->interrupt_in_buffer);
+
+ usb_free_urb(edge_serial->read_urb);
+ kfree(edge_serial->bulk_in_buffer);
+
+ kfree(edge_serial);
+
+ return response;
}
/* start interrupt read for this edgeport this interrupt will