Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5c0c555 authored by Johan Hovold's avatar Johan Hovold
Browse files

USB: serial: io_edgeport: fix memory leaks in attach error path



Private data, URBs and buffers allocated for Epic devices during
attach were never released on errors (e.g. missing endpoints).

Fixes: 6e8cf775 ("USB: add EPIC support to the io_edgeport driver")
Cc: stable <stable@vger.kernel.org>	# v2.6.21
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ab5701ad
Loading
Loading
Loading
Loading
+28 −11
Original line number Diff line number Diff line
@@ -2849,14 +2849,16 @@ static int edge_startup(struct usb_serial *serial)
				/* not set up yet, so do it now */
				edge_serial->interrupt_read_urb =
						usb_alloc_urb(0, GFP_KERNEL);
				if (!edge_serial->interrupt_read_urb)
					return -ENOMEM;
				if (!edge_serial->interrupt_read_urb) {
					response = -ENOMEM;
					break;
				}

				edge_serial->interrupt_in_buffer =
					kmalloc(buffer_size, GFP_KERNEL);
				if (!edge_serial->interrupt_in_buffer) {
					usb_free_urb(edge_serial->interrupt_read_urb);
					return -ENOMEM;
					response = -ENOMEM;
					break;
				}
				edge_serial->interrupt_in_endpoint =
						endpoint->bEndpointAddress;
@@ -2884,14 +2886,16 @@ static int edge_startup(struct usb_serial *serial)
				/* not set up yet, so do it now */
				edge_serial->read_urb =
						usb_alloc_urb(0, GFP_KERNEL);
				if (!edge_serial->read_urb)
					return -ENOMEM;
				if (!edge_serial->read_urb) {
					response = -ENOMEM;
					break;
				}

				edge_serial->bulk_in_buffer =
					kmalloc(buffer_size, GFP_KERNEL);
				if (!edge_serial->bulk_in_buffer) {
					usb_free_urb(edge_serial->read_urb);
					return -ENOMEM;
					response = -ENOMEM;
					break;
				}
				edge_serial->bulk_in_endpoint =
						endpoint->bEndpointAddress;
@@ -2917,9 +2921,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