Commit 6f965989 authored by Jiri Kosina's avatar Jiri Kosina
Browse files

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)
parents ad78d7e3 a0580023
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
		goto cleanup;

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

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

	/* Send the ack */
	memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
+4 −1
Original line number Diff line number Diff line
@@ -1063,7 +1063,7 @@ bool hid_ignore(struct hid_device *hdev)
	}

	if (hdev->type == HID_TYPE_USBMOUSE &&
	    hid_match_id(hdev, hid_mouse_ignore_list))
	    hdev->quirks & HID_QUIRK_IGNORE_MOUSE)
		return true;

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

	if (hid_match_id(hdev, hid_mouse_ignore_list))
		quirks |= HID_QUIRK_IGNORE_MOUSE;

	if (hid_match_id(hdev, hid_have_special_driver))
		quirks |= HID_QUIRK_HAVE_SPECIAL_DRIVER;

+14 −11
Original line number Diff line number Diff line
@@ -984,12 +984,11 @@ static int usbhid_parse(struct hid_device *hid)
	struct usb_host_interface *interface = intf->cur_altsetting;
	struct usb_device *dev = interface_to_usbdev (intf);
	struct hid_descriptor *hdesc;
	struct hid_class_descriptor *hcdesc;
	u32 quirks = 0;
	unsigned int rsize = 0;
	char *rdesc;
	int ret, n;
	int num_descriptors;
	size_t offset = offsetof(struct hid_descriptor, desc);
	int ret;

	quirks = hid_lookup_quirk(hid);

@@ -1011,20 +1010,19 @@ 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");
	if (!hdesc->bNumDescriptors ||
	    hdesc->bLength != sizeof(*hdesc) +
			      (hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) {
		dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n",
			hdesc->bLength, hdesc->bNumDescriptors);
		return -EINVAL;
	}

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

	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);
	if (hdesc->rpt_desc.bDescriptorType == HID_DT_REPORT)
		rsize = le16_to_cpu(hdesc->rpt_desc.wDescriptorLength);

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

	if (hdesc->bNumDescriptors > 1)
		hid_warn(intf,
			"%u unsupported optional hid class descriptors\n",
			(int)(hdesc->bNumDescriptors - 1));

	hid->quirks |= quirks;

	return 0;
+6 −6
Original line number Diff line number Diff line
@@ -144,8 +144,8 @@ static struct hid_descriptor hidg_desc = {
	.bcdHID				= cpu_to_le16(0x0101),
	.bCountryCode			= 0x00,
	.bNumDescriptors		= 0x1,
	/*.desc[0].bDescriptorType	= DYNAMIC */
	/*.desc[0].wDescriptorLenght	= DYNAMIC */
	/*.rpt_desc.bDescriptorType	= DYNAMIC */
	/*.rpt_desc.wDescriptorLength	= DYNAMIC */
};

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

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

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

	hidg_hs_in_ep_desc.bEndpointAddress =
+4 −1
Original line number Diff line number Diff line
@@ -357,6 +357,7 @@ struct hid_item {
 * | @HID_QUIRK_INPUT_PER_APP:
 * | @HID_QUIRK_X_INVERT:
 * | @HID_QUIRK_Y_INVERT:
 * | @HID_QUIRK_IGNORE_MOUSE:
 * | @HID_QUIRK_SKIP_OUTPUT_REPORTS:
 * | @HID_QUIRK_SKIP_OUTPUT_REPORT_ID:
 * | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP:
@@ -382,6 +383,7 @@ struct hid_item {
#define HID_QUIRK_INPUT_PER_APP			BIT(11)
#define HID_QUIRK_X_INVERT			BIT(12)
#define HID_QUIRK_Y_INVERT			BIT(13)
#define HID_QUIRK_IGNORE_MOUSE			BIT(14)
#define HID_QUIRK_SKIP_OUTPUT_REPORTS		BIT(16)
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID		BIT(17)
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP	BIT(18)
@@ -740,8 +742,9 @@ struct hid_descriptor {
	__le16 bcdHID;
	__u8  bCountryCode;
	__u8  bNumDescriptors;
	struct hid_class_descriptor rpt_desc;

	struct hid_class_descriptor desc[1];
	struct hid_class_descriptor opt_descs[];
} __attribute__ ((packed));

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