Skip to content

Commit f579530

Browse files
Benjamin Tissoiresgregkh
authored andcommitted
HID: usbhid: paper over wrong bNumDescriptor field
commit f28beb6 upstream. Some faulty devices (ZWO EFWmini) have a wrong optional HID class descriptor count compared to the provided length. Given that we plainly ignore those optional descriptor, we can attempt to fix the provided number so we do not lock out those devices. Signed-off-by: Benjamin Tissoires <[email protected]> Cc: Salvatore Bonaccorso <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 0754d5c commit f579530

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

drivers/hid/usbhid/hid-core.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,7 @@ static int usbhid_parse(struct hid_device *hid)
985985
struct usb_device *dev = interface_to_usbdev (intf);
986986
struct hid_descriptor *hdesc;
987987
struct hid_class_descriptor *hcdesc;
988+
__u8 fixed_opt_descriptors_size;
988989
u32 quirks = 0;
989990
unsigned int rsize = 0;
990991
char *rdesc;
@@ -1015,7 +1016,21 @@ static int usbhid_parse(struct hid_device *hid)
10151016
(hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) {
10161017
dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n",
10171018
hdesc->bLength, hdesc->bNumDescriptors);
1018-
return -EINVAL;
1019+
1020+
/*
1021+
* Some devices may expose a wrong number of descriptors compared
1022+
* to the provided length.
1023+
* However, we ignore the optional hid class descriptors entirely
1024+
* so we can safely recompute the proper field.
1025+
*/
1026+
if (hdesc->bLength >= sizeof(*hdesc)) {
1027+
fixed_opt_descriptors_size = hdesc->bLength - sizeof(*hdesc);
1028+
1029+
hid_warn(intf, "fixing wrong optional hid class descriptors count\n");
1030+
hdesc->bNumDescriptors = fixed_opt_descriptors_size / sizeof(*hcdesc) + 1;
1031+
} else {
1032+
return -EINVAL;
1033+
}
10191034
}
10201035

10211036
hid->version = le16_to_cpu(hdesc->bcdHID);

0 commit comments

Comments
 (0)