]> git.hungrycats.org Git - linux/commitdiff
USB: serial: io_edgeport: fix memory leaks in attach error path
authorJohan Hovold <johan@kernel.org>
Sun, 8 May 2016 18:07:56 +0000 (20:07 +0200)
committerJiri Slaby <jslaby@suse.cz>
Wed, 15 Jun 2016 07:32:07 +0000 (09:32 +0200)
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>
drivers/usb/serial/io_edgeport.c

index c91481d74a144fd2ae2810a2f778b30a63e78310..60bff3b7560910a0ae7b5a388eb5c666782bb684 100644 (file)
@@ -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