On 06/25/10 12:32, Gianni Tedesco wrote:
> A device MAY provide extended descriptors in 2 ways mentioned in the
> spec, but ISTR finding at least one device in the wild with standard
> descriptors extended which were not so much used by the "host" but by
> application software. So not sure about your patch, a quirks blacklist
> based on idDevice/idProduct might be the better fix here.

Makes sense. I should add vend/prod id check.

> However the more serious problem is spinning on zero length descriptor
> when truncated descriptors are not valid and zero length (in fact < 2)
> is totally unacceptable. Following patch checks for truncation.

Gianni, Please check my later patch submitted last night. I basically did the
same thing you did, but with few differences:

- if descriptor size is < 2, goto fail
- if the descriptor is USB_DT_CONFIG, we can skip through all the sub
descriptors using wTotalLength field.
- otherwise, simply skip it

One thing to also watch out for is the string descriptors. I might be wrong, but
it appears (from reading the doc) that string descriptors (at least for the
device descriptor) can be interspersed with the config descriptors, in which
case (config_descr_len < USB_DT_CONFIG_SIZE) without checking descriptor type
might unwittingly lead to failure.

-TJ

> diff --git a/hw/usb.h b/hw/usb.h
> index 00d2802..efd4a65 100644
> --- a/hw/usb.h
> +++ b/hw/usb.h
> @@ -117,6 +117,14 @@
>  #define USB_DT_INTERFACE             0x04
>  #define USB_DT_ENDPOINT                      0x05
>  
> +/*
> + * Descriptor sizes per descriptor type
> + */
> +#define USB_DT_DEVICE_SIZE           18
> +#define USB_DT_CONFIG_SIZE           9
> +#define USB_DT_INTERFACE_SIZE                9
> +#define USB_DT_ENDPOINT_SIZE         7
> +
>  #define USB_ENDPOINT_XFER_CONTROL    0
>  #define USB_ENDPOINT_XFER_ISOC               1
>  #define USB_ENDPOINT_XFER_BULK               2
> diff --git a/usb-linux.c b/usb-linux.c
> index 88273ff..d259290 100644
> --- a/usb-linux.c
> +++ b/usb-linux.c
> @@ -299,7 +299,7 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, 
> int configuration)
>  
>      i = 0;
>      dev_descr_len = dev->descr[0];
> -    if (dev_descr_len > dev->descr_len) {
> +    if ( dev_descr_len < USB_DT_DEVICE_SIZE || dev_descr_len > 
> dev->descr_len) {
>          goto fail;
>      }
>  
> @@ -314,6 +314,8 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, 
> int configuration)
>              continue;
>          }
>          config_descr_len = dev->descr[i];
> +        if ( config_descr_len < USB_DT_CONFIG_SIZE )
> +            goto fail;
>  
>          printf("husb: config #%d need %d\n", dev->descr[i + 5], 
> configuration);
>  

Reply via email to