On Mon, 21 Oct 2013, Huang Rui wrote:
> In Test 9 of usbtest module, it is used for performing chapter 9 tests N
> times.
>
> USB2.0 Extension descriptor is one of the generic device-level capbility
> descriptors which added in section 9.6.2.1 of USB 3.0 spec.
>
> This patch adds to support getting usb2.0 extension descriptor test
> scenario for USB 3.0.
>
> Signed-off-by: Huang Rui <[email protected]>
...
> @@ -694,12 +716,56 @@ static int ch9_postconfig(struct usbtest_dev *dev)
> * 3.0 spec
> */
> if (le16_to_cpu(udev->descriptor.bcdUSB) == 0x0300) {
> + struct usb_bos_descriptor *bos = NULL;
> + struct usb_dev_cap_header *header = NULL;
> + unsigned total, num, length;
> +
> retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
> sizeof(*udev->bos->desc));
> if (retval != sizeof(*udev->bos->desc)) {
> dev_err(&iface->dev, "bos descriptor --> %d\n", retval);
> return (retval < 0) ? retval : -EDOM;
> }
> +
> + bos = (struct usb_bos_descriptor *)dev->buf;
> + total = le16_to_cpu(bos->wTotalLength);
> + num = bos->bNumDeviceCaps;
> +
> + /*
> + * get generic device-level capability descriptors [9.6.2]
> + * in USB 3.0 spec
> + */
> + retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
> + total);
This exposes the kernel to a buffer overflow bug. Remember, dev->buf
is only 256 bytes long. What happens if total > 256?
> + if (retval != total) {
> + dev_err(&iface->dev, "bos descriptor set --> %d\n",
> + retval);
> + return (retval < 0) ? retval : -EDOM;
> + }
> +
> + length = sizeof(*udev->bos->desc);
> + for (i = 0; i < num; i++) {
> + dev->buf += length;
What will happen when the code further down uses dev->buf to hold
config descriptors? You should use a local pointer here; don't change
dev->buf.
What happens if the new value of the pointer lies beyond the end of the
dev->buf?
> + header = (struct usb_dev_cap_header *)dev->buf;
> + length = header->bLength;
> +
> + if (header->bDescriptorType !=
> + USB_DT_DEVICE_CAPABILITY) {
> + dev_warn(&udev->dev, "not device capability
> descriptor, skip\n");
> + continue;
> + }
> +
> + switch (header->bDevCapabilityType) {
> + case USB_CAP_TYPE_EXT:
> + if (!is_good_ext(dev)) {
What happens if header points to a location only 1 or 2 bytes before
the end of dev->buf?
> + dev_err(&iface->dev, "bogus usb 2.0
> extension descriptor\n");
> + return -EDOM;
> + }
> + break;
> + default:
> + break;
> + }
> + }
> }
Alan Stern
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html