Commit d979e9f9 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

USB: serial: fix potential stack buffer overflow



Make sure to verify the maximum number of endpoints per type to avoid
writing beyond the end of a stack-allocated array.

The current usb-serial implementation is limited to eight ports per
interface but failed to verify that the number of endpoints of a certain
type reported by a device did not exceed this limit.

Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 03936890
Loading
Loading
Loading
Loading
+22 −10
Original line number Diff line number Diff line
@@ -764,31 +764,41 @@ static int usb_serial_probe(struct usb_interface *interface,
		if (usb_endpoint_is_bulk_in(endpoint)) {
			/* we found a bulk in endpoint */
			dev_dbg(ddev, "found bulk in on endpoint %d\n", i);
			if (num_bulk_in < MAX_NUM_PORTS) {
				bulk_in_endpoint[num_bulk_in] = endpoint;
				++num_bulk_in;
			}
		}

		if (usb_endpoint_is_bulk_out(endpoint)) {
			/* we found a bulk out endpoint */
			dev_dbg(ddev, "found bulk out on endpoint %d\n", i);
			if (num_bulk_out < MAX_NUM_PORTS) {
				bulk_out_endpoint[num_bulk_out] = endpoint;
				++num_bulk_out;
			}
		}

		if (usb_endpoint_is_int_in(endpoint)) {
			/* we found a interrupt in endpoint */
			dev_dbg(ddev, "found interrupt in on endpoint %d\n", i);
			interrupt_in_endpoint[num_interrupt_in] = endpoint;
			if (num_interrupt_in < MAX_NUM_PORTS) {
				interrupt_in_endpoint[num_interrupt_in] =
						endpoint;
				++num_interrupt_in;
			}
		}

		if (usb_endpoint_is_int_out(endpoint)) {
			/* we found an interrupt out endpoint */
			dev_dbg(ddev, "found interrupt out on endpoint %d\n", i);
			interrupt_out_endpoint[num_interrupt_out] = endpoint;
			if (num_interrupt_out < MAX_NUM_PORTS) {
				interrupt_out_endpoint[num_interrupt_out] =
						endpoint;
				++num_interrupt_out;
			}
		}
	}

#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)
	/* BEGIN HORRIBLE HACK FOR PL2303 */
@@ -809,11 +819,13 @@ static int usb_serial_probe(struct usb_interface *interface,
				if (usb_endpoint_is_int_in(endpoint)) {
					/* we found a interrupt in endpoint */
					dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n");
					if (num_interrupt_in < MAX_NUM_PORTS) {
						interrupt_in_endpoint[num_interrupt_in] = endpoint;
						++num_interrupt_in;
					}
				}
			}
		}

		/* Now make sure the PL-2303 is configured correctly.
		 * If not, give up now and hope this hack will work