From f3ffd331125178e649bad2c76d3c0a7acfba8c9d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 9 Dec 2021 22:16:37 +0100 Subject: [PATCH] 4.4-stable patches added patches: hid-check-for-valid-usb-device-for-many-hid-drivers.patch hid-wacom-fix-problems-when-device-is-not-a-valid-usb-device.patch --- ...alid-usb-device-for-many-hid-drivers.patch | 334 ++++++++++++++++++ ...hen-device-is-not-a-valid-usb-device.patch | 75 ++++ queue-4.4/series | 2 + 3 files changed, 411 insertions(+) create mode 100644 queue-4.4/hid-check-for-valid-usb-device-for-many-hid-drivers.patch create mode 100644 queue-4.4/hid-wacom-fix-problems-when-device-is-not-a-valid-usb-device.patch diff --git a/queue-4.4/hid-check-for-valid-usb-device-for-many-hid-drivers.patch b/queue-4.4/hid-check-for-valid-usb-device-for-many-hid-drivers.patch new file mode 100644 index 00000000000..acd1a11f824 --- /dev/null +++ b/queue-4.4/hid-check-for-valid-usb-device-for-many-hid-drivers.patch @@ -0,0 +1,334 @@ +From 93020953d0fa7035fd036ad87a47ae2b7aa4ae33 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 1 Dec 2021 19:35:03 +0100 +Subject: HID: check for valid USB device for many HID drivers + +From: Greg Kroah-Hartman + +commit 93020953d0fa7035fd036ad87a47ae2b7aa4ae33 upstream. + +Many HID drivers assume that the HID device assigned to them is a USB +device as that was the only way HID devices used to be able to be +created in Linux. However, with the additional ways that HID devices +can be created for many different bus types, that is no longer true, so +properly check that we have a USB device associated with the HID device +before allowing a driver that makes this assumption to claim it. + +Cc: Jiri Kosina +Cc: Benjamin Tissoires +Cc: Michael Zaidman +Cc: Stefan Achatz +Cc: Maxime Coquelin +Cc: Alexandre Torgue +Cc: linux-input@vger.kernel.org +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +Tested-by: Benjamin Tissoires +[bentiss: amended for thrustmater.c hunk to apply] +Signed-off-by: Benjamin Tissoires +Link: https://lore.kernel.org/r/20211201183503.2373082-3-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-chicony.c | 8 ++++++-- + drivers/hid/hid-corsair.c | 7 ++++++- + drivers/hid/hid-elo.c | 3 +++ + drivers/hid/hid-holtek-kbd.c | 9 +++++++-- + drivers/hid/hid-holtek-mouse.c | 9 +++++++++ + drivers/hid/hid-lg.c | 10 ++++++++-- + drivers/hid/hid-prodikeys.c | 10 ++++++++-- + drivers/hid/hid-roccat-arvo.c | 3 +++ + drivers/hid/hid-roccat-isku.c | 3 +++ + drivers/hid/hid-roccat-kone.c | 3 +++ + drivers/hid/hid-roccat-koneplus.c | 3 +++ + drivers/hid/hid-roccat-konepure.c | 3 +++ + drivers/hid/hid-roccat-kovaplus.c | 3 +++ + drivers/hid/hid-roccat-lua.c | 3 +++ + drivers/hid/hid-roccat-pyra.c | 3 +++ + drivers/hid/hid-roccat-ryos.c | 3 +++ + drivers/hid/hid-roccat-savu.c | 3 +++ + drivers/hid/hid-samsung.c | 3 +++ + drivers/hid/hid-uclogic.c | 3 +++ + 19 files changed, 83 insertions(+), 9 deletions(-) + +--- a/drivers/hid/hid-chicony.c ++++ b/drivers/hid/hid-chicony.c +@@ -61,8 +61,12 @@ static int ch_input_mapping(struct hid_d + static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) + { +- struct usb_interface *intf = to_usb_interface(hdev->dev.parent); +- ++ struct usb_interface *intf; ++ ++ if (!hid_is_usb(hdev)) ++ return rdesc; ++ ++ intf = to_usb_interface(hdev->dev.parent); + if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { + /* Change usage maximum and logical maximum from 0x7fff to + * 0x2fff, so they don't exceed HID_MAX_USAGES */ +--- a/drivers/hid/hid-corsair.c ++++ b/drivers/hid/hid-corsair.c +@@ -551,7 +551,12 @@ static int corsair_probe(struct hid_devi + int ret; + unsigned long quirks = id->driver_data; + struct corsair_drvdata *drvdata; +- struct usb_interface *usbif = to_usb_interface(dev->dev.parent); ++ struct usb_interface *usbif; ++ ++ if (!hid_is_usb(dev)) ++ return -EINVAL; ++ ++ usbif = to_usb_interface(dev->dev.parent); + + drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata), + GFP_KERNEL); +--- a/drivers/hid/hid-elo.c ++++ b/drivers/hid/hid-elo.c +@@ -230,6 +230,9 @@ static int elo_probe(struct hid_device * + struct elo_priv *priv; + int ret; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; +--- a/drivers/hid/hid-holtek-kbd.c ++++ b/drivers/hid/hid-holtek-kbd.c +@@ -143,12 +143,17 @@ static int holtek_kbd_input_event(struct + static int holtek_kbd_probe(struct hid_device *hdev, + const struct hid_device_id *id) + { +- struct usb_interface *intf = to_usb_interface(hdev->dev.parent); +- int ret = hid_parse(hdev); ++ struct usb_interface *intf; ++ int ret; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ ++ ret = hid_parse(hdev); + if (!ret) + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + ++ intf = to_usb_interface(hdev->dev.parent); + if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) { + struct hid_input *hidinput; + list_for_each_entry(hidinput, &hdev->inputs, list) { +--- a/drivers/hid/hid-holtek-mouse.c ++++ b/drivers/hid/hid-holtek-mouse.c +@@ -65,6 +65,14 @@ static __u8 *holtek_mouse_report_fixup(s + return rdesc; + } + ++static int holtek_mouse_probe(struct hid_device *hdev, ++ const struct hid_device_id *id) ++{ ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ return 0; ++} ++ + static const struct hid_device_id holtek_mouse_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, + USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, +@@ -86,6 +94,7 @@ static struct hid_driver holtek_mouse_dr + .name = "holtek_mouse", + .id_table = holtek_mouse_devices, + .report_fixup = holtek_mouse_report_fixup, ++ .probe = holtek_mouse_probe, + }; + + module_hid_driver(holtek_mouse_driver); +--- a/drivers/hid/hid-lg.c ++++ b/drivers/hid/hid-lg.c +@@ -659,12 +659,18 @@ static int lg_event(struct hid_device *h + + static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) + { +- struct usb_interface *iface = to_usb_interface(hdev->dev.parent); +- __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; ++ struct usb_interface *iface; ++ __u8 iface_num; + unsigned int connect_mask = HID_CONNECT_DEFAULT; + struct lg_drv_data *drv_data; + int ret; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ ++ iface = to_usb_interface(hdev->dev.parent); ++ iface_num = iface->cur_altsetting->desc.bInterfaceNumber; ++ + /* G29 only work with the 1st interface */ + if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && + (iface_num != 0)) { +--- a/drivers/hid/hid-prodikeys.c ++++ b/drivers/hid/hid-prodikeys.c +@@ -803,12 +803,18 @@ static int pk_raw_event(struct hid_devic + static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) + { + int ret; +- struct usb_interface *intf = to_usb_interface(hdev->dev.parent); +- unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber; ++ struct usb_interface *intf; ++ unsigned short ifnum; + unsigned long quirks = id->driver_data; + struct pk_device *pk; + struct pcmidi_snd *pm = NULL; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ ++ intf = to_usb_interface(hdev->dev.parent); ++ ifnum = intf->cur_altsetting->desc.bInterfaceNumber; ++ + pk = kzalloc(sizeof(*pk), GFP_KERNEL); + if (pk == NULL) { + hid_err(hdev, "can't alloc descriptor\n"); +--- a/drivers/hid/hid-roccat-arvo.c ++++ b/drivers/hid/hid-roccat-arvo.c +@@ -349,6 +349,9 @@ static int arvo_probe(struct hid_device + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-isku.c ++++ b/drivers/hid/hid-roccat-isku.c +@@ -329,6 +329,9 @@ static int isku_probe(struct hid_device + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-kone.c ++++ b/drivers/hid/hid-roccat-kone.c +@@ -756,6 +756,9 @@ static int kone_probe(struct hid_device + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-koneplus.c ++++ b/drivers/hid/hid-roccat-koneplus.c +@@ -438,6 +438,9 @@ static int koneplus_probe(struct hid_dev + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-konepure.c ++++ b/drivers/hid/hid-roccat-konepure.c +@@ -136,6 +136,9 @@ static int konepure_probe(struct hid_dev + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-kovaplus.c ++++ b/drivers/hid/hid-roccat-kovaplus.c +@@ -508,6 +508,9 @@ static int kovaplus_probe(struct hid_dev + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-lua.c ++++ b/drivers/hid/hid-roccat-lua.c +@@ -163,6 +163,9 @@ static int lua_probe(struct hid_device * + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-pyra.c ++++ b/drivers/hid/hid-roccat-pyra.c +@@ -457,6 +457,9 @@ static int pyra_probe(struct hid_device + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-ryos.c ++++ b/drivers/hid/hid-roccat-ryos.c +@@ -144,6 +144,9 @@ static int ryos_probe(struct hid_device + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-roccat-savu.c ++++ b/drivers/hid/hid-roccat-savu.c +@@ -116,6 +116,9 @@ static int savu_probe(struct hid_device + { + int retval; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + retval = hid_parse(hdev); + if (retval) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-samsung.c ++++ b/drivers/hid/hid-samsung.c +@@ -157,6 +157,9 @@ static int samsung_probe(struct hid_devi + int ret; + unsigned int cmask = HID_CONNECT_DEFAULT; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed\n"); +--- a/drivers/hid/hid-uclogic.c ++++ b/drivers/hid/hid-uclogic.c +@@ -795,6 +795,9 @@ static int uclogic_tablet_enable(struct + __u8 *p; + s32 v; + ++ if (!hid_is_usb(hdev)) ++ return -EINVAL; ++ + /* + * Read string descriptor containing tablet parameters. The specific + * string descriptor and data were discovered by sniffing the Windows diff --git a/queue-4.4/hid-wacom-fix-problems-when-device-is-not-a-valid-usb-device.patch b/queue-4.4/hid-wacom-fix-problems-when-device-is-not-a-valid-usb-device.patch new file mode 100644 index 00000000000..8f35377fff2 --- /dev/null +++ b/queue-4.4/hid-wacom-fix-problems-when-device-is-not-a-valid-usb-device.patch @@ -0,0 +1,75 @@ +From 720ac467204a70308bd687927ed475afb904e11b Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 1 Dec 2021 19:35:02 +0100 +Subject: HID: wacom: fix problems when device is not a valid USB device + +From: Greg Kroah-Hartman + +commit 720ac467204a70308bd687927ed475afb904e11b upstream. + +The wacom driver accepts devices of more than just USB types, but some +code paths can cause problems if the device being controlled is not a +USB device due to a lack of checking. Add the needed checks to ensure +that the USB device accesses are only happening on a "real" USB device, +and not one on some other bus. + +Cc: Jiri Kosina +Cc: Benjamin Tissoires +Cc: linux-input@vger.kernel.org +Cc: stable@vger.kernel.org +Tested-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Benjamin Tissoires +Link: https://lore.kernel.org/r/20211201183503.2373082-2-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/wacom_sys.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/drivers/hid/wacom_sys.c ++++ b/drivers/hid/wacom_sys.c +@@ -458,7 +458,7 @@ static void wacom_retrieve_hid_descripto + * Skip the query for this type and modify defaults based on + * interface number. + */ +- if (features->type == WIRELESS) { ++ if (features->type == WIRELESS && intf) { + if (intf->cur_altsetting->desc.bInterfaceNumber == 0) + features->device_type = WACOM_DEVICETYPE_WL_MONITOR; + else +@@ -1512,6 +1512,9 @@ static void wacom_wireless_work(struct w + + wacom_destroy_battery(wacom); + ++ if (!usbdev) ++ return; ++ + /* Stylus interface */ + hdev1 = usb_get_intfdata(usbdev->config->interface[1]); + wacom1 = hid_get_drvdata(hdev1); +@@ -1689,8 +1692,6 @@ static void wacom_update_name(struct wac + static int wacom_probe(struct hid_device *hdev, + const struct hid_device_id *id) + { +- struct usb_interface *intf = to_usb_interface(hdev->dev.parent); +- struct usb_device *dev = interface_to_usbdev(intf); + struct wacom *wacom; + struct wacom_wac *wacom_wac; + struct wacom_features *features; +@@ -1733,8 +1734,14 @@ static int wacom_probe(struct hid_device + goto fail_type; + } + +- wacom->usbdev = dev; +- wacom->intf = intf; ++ if (hid_is_usb(hdev)) { ++ struct usb_interface *intf = to_usb_interface(hdev->dev.parent); ++ struct usb_device *dev = interface_to_usbdev(intf); ++ ++ wacom->usbdev = dev; ++ wacom->intf = intf; ++ } ++ + mutex_init(&wacom->lock); + INIT_WORK(&wacom->work, wacom_wireless_work); + diff --git a/queue-4.4/series b/queue-4.4/series index 8d9c0e5f07e..33eeaee0815 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -3,3 +3,5 @@ hid-add-hid_is_usb-function-to-make-it-simpler-for-usb-detection.patch hid-add-usb_hid-dependancy-to-hid-prodikeys.patch hid-add-usb_hid-dependancy-to-hid-chicony.patch hid-add-usb_hid-dependancy-on-some-usb-hid-drivers.patch +hid-wacom-fix-problems-when-device-is-not-a-valid-usb-device.patch +hid-check-for-valid-usb-device-for-many-hid-drivers.patch -- 2.47.2