|
@@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
- while (buflen > 0) {
|
|
|
|
|
|
+ while (buflen >= sizeof(*union_desc)) {
|
|
union_desc = (struct usb_cdc_union_desc *)buf;
|
|
union_desc = (struct usb_cdc_union_desc *)buf;
|
|
|
|
|
|
|
|
+ if (union_desc->bLength > buflen) {
|
|
|
|
+ dev_err(&intf->dev, "Too large descriptor\n");
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
|
|
if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
|
|
union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
|
|
union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
|
|
dev_dbg(&intf->dev, "Found union header\n");
|
|
dev_dbg(&intf->dev, "Found union header\n");
|
|
- return union_desc;
|
|
|
|
|
|
+
|
|
|
|
+ if (union_desc->bLength >= sizeof(*union_desc))
|
|
|
|
+ return union_desc;
|
|
|
|
+
|
|
|
|
+ dev_err(&intf->dev,
|
|
|
|
+ "Union descriptor to short (%d vs %zd\n)",
|
|
|
|
+ union_desc->bLength, sizeof(*union_desc));
|
|
|
|
+ return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
buflen -= union_desc->bLength;
|
|
buflen -= union_desc->bLength;
|