Skip to content

Commit 6f96598

Browse files
author
Jiri Kosina
committed
Merge branch 'for-6.16/core' into for-linus
- make it possible to set hid_mouse_ignore_list dynamically (the same way we handle other quirks) (Aditya Garg) - fix potential OOB in usbhid_parse() (Terry Junge)
2 parents ad78d7e + a058002 commit 6f96598

File tree

5 files changed

+30
-21
lines changed

5 files changed

+30
-21
lines changed

drivers/hid/hid-hyperv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
192192
goto cleanup;
193193

194194
input_device->report_desc_size = le16_to_cpu(
195-
desc->desc[0].wDescriptorLength);
195+
desc->rpt_desc.wDescriptorLength);
196196
if (input_device->report_desc_size == 0) {
197197
input_device->dev_info_status = -EINVAL;
198198
goto cleanup;
@@ -210,7 +210,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
210210

211211
memcpy(input_device->report_desc,
212212
((unsigned char *)desc) + desc->bLength,
213-
le16_to_cpu(desc->desc[0].wDescriptorLength));
213+
le16_to_cpu(desc->rpt_desc.wDescriptorLength));
214214

215215
/* Send the ack */
216216
memset(&ack, 0, sizeof(struct mousevsc_prt_msg));

drivers/hid/hid-quirks.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ bool hid_ignore(struct hid_device *hdev)
10631063
}
10641064

10651065
if (hdev->type == HID_TYPE_USBMOUSE &&
1066-
hid_match_id(hdev, hid_mouse_ignore_list))
1066+
hdev->quirks & HID_QUIRK_IGNORE_MOUSE)
10671067
return true;
10681068

10691069
return !!hid_match_id(hdev, hid_ignore_list);
@@ -1267,6 +1267,9 @@ static unsigned long hid_gets_squirk(const struct hid_device *hdev)
12671267
if (hid_match_id(hdev, hid_ignore_list))
12681268
quirks |= HID_QUIRK_IGNORE;
12691269

1270+
if (hid_match_id(hdev, hid_mouse_ignore_list))
1271+
quirks |= HID_QUIRK_IGNORE_MOUSE;
1272+
12701273
if (hid_match_id(hdev, hid_have_special_driver))
12711274
quirks |= HID_QUIRK_HAVE_SPECIAL_DRIVER;
12721275

drivers/hid/usbhid/hid-core.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -984,12 +984,11 @@ static int usbhid_parse(struct hid_device *hid)
984984
struct usb_host_interface *interface = intf->cur_altsetting;
985985
struct usb_device *dev = interface_to_usbdev (intf);
986986
struct hid_descriptor *hdesc;
987+
struct hid_class_descriptor *hcdesc;
987988
u32 quirks = 0;
988989
unsigned int rsize = 0;
989990
char *rdesc;
990-
int ret, n;
991-
int num_descriptors;
992-
size_t offset = offsetof(struct hid_descriptor, desc);
991+
int ret;
993992

994993
quirks = hid_lookup_quirk(hid);
995994

@@ -1011,20 +1010,19 @@ static int usbhid_parse(struct hid_device *hid)
10111010
return -ENODEV;
10121011
}
10131012

1014-
if (hdesc->bLength < sizeof(struct hid_descriptor)) {
1015-
dbg_hid("hid descriptor is too short\n");
1013+
if (!hdesc->bNumDescriptors ||
1014+
hdesc->bLength != sizeof(*hdesc) +
1015+
(hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) {
1016+
dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n",
1017+
hdesc->bLength, hdesc->bNumDescriptors);
10161018
return -EINVAL;
10171019
}
10181020

10191021
hid->version = le16_to_cpu(hdesc->bcdHID);
10201022
hid->country = hdesc->bCountryCode;
10211023

1022-
num_descriptors = min_t(int, hdesc->bNumDescriptors,
1023-
(hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
1024-
1025-
for (n = 0; n < num_descriptors; n++)
1026-
if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
1027-
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
1024+
if (hdesc->rpt_desc.bDescriptorType == HID_DT_REPORT)
1025+
rsize = le16_to_cpu(hdesc->rpt_desc.wDescriptorLength);
10281026

10291027
if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
10301028
dbg_hid("weird size of report descriptor (%u)\n", rsize);
@@ -1052,6 +1050,11 @@ static int usbhid_parse(struct hid_device *hid)
10521050
goto err;
10531051
}
10541052

1053+
if (hdesc->bNumDescriptors > 1)
1054+
hid_warn(intf,
1055+
"%u unsupported optional hid class descriptors\n",
1056+
(int)(hdesc->bNumDescriptors - 1));
1057+
10551058
hid->quirks |= quirks;
10561059

10571060
return 0;

drivers/usb/gadget/function/f_hid.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ static struct hid_descriptor hidg_desc = {
144144
.bcdHID = cpu_to_le16(0x0101),
145145
.bCountryCode = 0x00,
146146
.bNumDescriptors = 0x1,
147-
/*.desc[0].bDescriptorType = DYNAMIC */
148-
/*.desc[0].wDescriptorLenght = DYNAMIC */
147+
/*.rpt_desc.bDescriptorType = DYNAMIC */
148+
/*.rpt_desc.wDescriptorLength = DYNAMIC */
149149
};
150150

151151
/* Super-Speed Support */
@@ -939,8 +939,8 @@ static int hidg_setup(struct usb_function *f,
939939
struct hid_descriptor hidg_desc_copy = hidg_desc;
940940

941941
VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n");
942-
hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT;
943-
hidg_desc_copy.desc[0].wDescriptorLength =
942+
hidg_desc_copy.rpt_desc.bDescriptorType = HID_DT_REPORT;
943+
hidg_desc_copy.rpt_desc.wDescriptorLength =
944944
cpu_to_le16(hidg->report_desc_length);
945945

946946
length = min_t(unsigned short, length,
@@ -1210,8 +1210,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
12101210
* We can use hidg_desc struct here but we should not relay
12111211
* that its content won't change after returning from this function.
12121212
*/
1213-
hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT;
1214-
hidg_desc.desc[0].wDescriptorLength =
1213+
hidg_desc.rpt_desc.bDescriptorType = HID_DT_REPORT;
1214+
hidg_desc.rpt_desc.wDescriptorLength =
12151215
cpu_to_le16(hidg->report_desc_length);
12161216

12171217
hidg_hs_in_ep_desc.bEndpointAddress =

include/linux/hid.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ struct hid_item {
357357
* | @HID_QUIRK_INPUT_PER_APP:
358358
* | @HID_QUIRK_X_INVERT:
359359
* | @HID_QUIRK_Y_INVERT:
360+
* | @HID_QUIRK_IGNORE_MOUSE:
360361
* | @HID_QUIRK_SKIP_OUTPUT_REPORTS:
361362
* | @HID_QUIRK_SKIP_OUTPUT_REPORT_ID:
362363
* | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP:
@@ -382,6 +383,7 @@ struct hid_item {
382383
#define HID_QUIRK_INPUT_PER_APP BIT(11)
383384
#define HID_QUIRK_X_INVERT BIT(12)
384385
#define HID_QUIRK_Y_INVERT BIT(13)
386+
#define HID_QUIRK_IGNORE_MOUSE BIT(14)
385387
#define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16)
386388
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17)
387389
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
@@ -740,8 +742,9 @@ struct hid_descriptor {
740742
__le16 bcdHID;
741743
__u8 bCountryCode;
742744
__u8 bNumDescriptors;
745+
struct hid_class_descriptor rpt_desc;
743746

744-
struct hid_class_descriptor desc[1];
747+
struct hid_class_descriptor opt_descs[];
745748
} __attribute__ ((packed));
746749

747750
#define HID_DEVICE(b, g, ven, prod) \

0 commit comments

Comments
 (0)