Skip to content

Commit 9302095

Browse files
gregkhbentiss
authored andcommitted
HID: check for valid USB device for many HID drivers
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 <[email protected]> Cc: Benjamin Tissoires <[email protected]> Cc: Michael Zaidman <[email protected]> Cc: Stefan Achatz <[email protected]> Cc: Maxime Coquelin <[email protected]> Cc: Alexandre Torgue <[email protected]> Cc: [email protected] Cc: [email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Tested-by: Benjamin Tissoires <[email protected]> [bentiss: amended for thrustmater.c hunk to apply] Signed-off-by: Benjamin Tissoires <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 720ac46 commit 9302095

23 files changed

+92
-9
lines changed

drivers/hid/hid-chicony.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ static int ch_probe(struct hid_device *hdev, const struct hid_device_id *id)
114114
{
115115
int ret;
116116

117+
if (!hid_is_usb(hdev))
118+
return -EINVAL;
119+
117120
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
118121
ret = hid_parse(hdev);
119122
if (ret) {

drivers/hid/hid-corsair.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,12 @@ static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id)
553553
int ret;
554554
unsigned long quirks = id->driver_data;
555555
struct corsair_drvdata *drvdata;
556-
struct usb_interface *usbif = to_usb_interface(dev->dev.parent);
556+
struct usb_interface *usbif;
557+
558+
if (!hid_is_usb(dev))
559+
return -EINVAL;
560+
561+
usbif = to_usb_interface(dev->dev.parent);
557562

558563
drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata),
559564
GFP_KERNEL);

drivers/hid/hid-elan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct elan_drvdata {
5050

5151
static int is_not_elan_touchpad(struct hid_device *hdev)
5252
{
53-
if (hdev->bus == BUS_USB) {
53+
if (hid_is_usb(hdev)) {
5454
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
5555

5656
return (intf->altsetting->desc.bInterfaceNumber !=

drivers/hid/hid-elo.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
230230
int ret;
231231
struct usb_device *udev;
232232

233+
if (!hid_is_usb(hdev))
234+
return -EINVAL;
235+
233236
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
234237
if (!priv)
235238
return -ENOMEM;

drivers/hid/hid-ft260.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,9 @@ static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id)
915915
struct ft260_get_chip_version_report version;
916916
int ret;
917917

918+
if (!hid_is_usb(hdev))
919+
return -EINVAL;
920+
918921
dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL);
919922
if (!dev)
920923
return -ENOMEM;

drivers/hid/hid-holtek-kbd.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,17 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type,
140140
static int holtek_kbd_probe(struct hid_device *hdev,
141141
const struct hid_device_id *id)
142142
{
143-
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
144-
int ret = hid_parse(hdev);
143+
struct usb_interface *intf;
144+
int ret;
145+
146+
if (!hid_is_usb(hdev))
147+
return -EINVAL;
145148

149+
ret = hid_parse(hdev);
146150
if (!ret)
147151
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
148152

153+
intf = to_usb_interface(hdev->dev.parent);
149154
if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) {
150155
struct hid_input *hidinput;
151156
list_for_each_entry(hidinput, &hdev->inputs, list) {

drivers/hid/hid-holtek-mouse.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
6262
return rdesc;
6363
}
6464

65+
static int holtek_mouse_probe(struct hid_device *hdev,
66+
const struct hid_device_id *id)
67+
{
68+
if (!hid_is_usb(hdev))
69+
return -EINVAL;
70+
return 0;
71+
}
72+
6573
static const struct hid_device_id holtek_mouse_devices[] = {
6674
{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
6775
USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
@@ -83,6 +91,7 @@ static struct hid_driver holtek_mouse_driver = {
8391
.name = "holtek_mouse",
8492
.id_table = holtek_mouse_devices,
8593
.report_fixup = holtek_mouse_report_fixup,
94+
.probe = holtek_mouse_probe,
8695
};
8796

8897
module_hid_driver(holtek_mouse_driver);

drivers/hid/hid-lg.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -749,12 +749,18 @@ static int lg_raw_event(struct hid_device *hdev, struct hid_report *report,
749749

750750
static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
751751
{
752-
struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
753-
__u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
752+
struct usb_interface *iface;
753+
__u8 iface_num;
754754
unsigned int connect_mask = HID_CONNECT_DEFAULT;
755755
struct lg_drv_data *drv_data;
756756
int ret;
757757

758+
if (!hid_is_usb(hdev))
759+
return -EINVAL;
760+
761+
iface = to_usb_interface(hdev->dev.parent);
762+
iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
763+
758764
/* G29 only work with the 1st interface */
759765
if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) &&
760766
(iface_num != 0)) {

drivers/hid/hid-prodikeys.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -798,12 +798,18 @@ static int pk_raw_event(struct hid_device *hdev, struct hid_report *report,
798798
static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id)
799799
{
800800
int ret;
801-
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
802-
unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
801+
struct usb_interface *intf;
802+
unsigned short ifnum;
803803
unsigned long quirks = id->driver_data;
804804
struct pk_device *pk;
805805
struct pcmidi_snd *pm = NULL;
806806

807+
if (!hid_is_usb(hdev))
808+
return -EINVAL;
809+
810+
intf = to_usb_interface(hdev->dev.parent);
811+
ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
812+
807813
pk = kzalloc(sizeof(*pk), GFP_KERNEL);
808814
if (pk == NULL) {
809815
hid_err(hdev, "can't alloc descriptor\n");

drivers/hid/hid-roccat-arvo.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ static int arvo_probe(struct hid_device *hdev,
344344
{
345345
int retval;
346346

347+
if (!hid_is_usb(hdev))
348+
return -EINVAL;
349+
347350
retval = hid_parse(hdev);
348351
if (retval) {
349352
hid_err(hdev, "parse failed\n");

0 commit comments

Comments
 (0)