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 <ray.huang@xxxxxxx> ... > @@ -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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html