diff options
author | Johan Hovold <johan@kernel.org> | 2016-05-08 20:07:56 +0200 |
---|---|---|
committer | Jiri Slaby <jslaby@suse.cz> | 2016-06-15 09:32:07 +0200 |
commit | 53ad8bf0a16b3d8e31b07004250f3468d279376c (patch) | |
tree | f0dff90d91cabb8450f49f35886c05cf7c9c309b /drivers/usb | |
parent | e78a0e1d718178cbee94a5d6f9ba109833708400 (diff) | |
download | lwn-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.c | 33 |
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 |