|
@@ -975,6 +975,8 @@ static int usbhid_parse(struct hid_device *hid)
|
|
|
unsigned int rsize = 0;
|
|
|
char *rdesc;
|
|
|
int ret, n;
|
|
|
+ int num_descriptors;
|
|
|
+ size_t offset = offsetof(struct hid_descriptor, desc);
|
|
|
|
|
|
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
|
|
|
le16_to_cpu(dev->descriptor.idProduct));
|
|
@@ -997,10 +999,18 @@ static int usbhid_parse(struct hid_device *hid)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
+ if (hdesc->bLength < sizeof(struct hid_descriptor)) {
|
|
|
+ dbg_hid("hid descriptor is too short\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
hid->version = le16_to_cpu(hdesc->bcdHID);
|
|
|
hid->country = hdesc->bCountryCode;
|
|
|
|
|
|
- for (n = 0; n < hdesc->bNumDescriptors; n++)
|
|
|
+ num_descriptors = min_t(int, hdesc->bNumDescriptors,
|
|
|
+ (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
|
|
|
+
|
|
|
+ for (n = 0; n < num_descriptors; n++)
|
|
|
if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
|
|
|
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
|
|
|
|