aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-10-12 12:08:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-10-12 12:08:56 -0400
commitbe7484acc6fee2878dc8d1593ba81fb1e0b3d581 (patch)
tree49d15b5652190a987e7a16019d80cc89764ef430
parent7702f47623e6c029b4ce59ce0ad39b869d5cc933 (diff)
parenta0933a456ff83a3b5ffa3a1903e0b8de4a56adf5 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID fixes from Jiri Kosina: - fix for potential out-of-bounds memory access (found by fuzzing, likely requires specially crafted device to trigger) by Jaejoong Kim - two new device IDs for elecom driver from Alex Manoussakis * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: HID: hid-elecom: extend to fix descriptor for HUGE trackball HID: usbhid: fix out-of-bounds bug
-rw-r--r--drivers/hid/Kconfig1
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-elecom.c13
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/hid/usbhid/hid-core.c12
5 files changed, 25 insertions, 5 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 0a3117cc29e7..374301fcbc86 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -281,6 +281,7 @@ config HID_ELECOM
281 Support for ELECOM devices: 281 Support for ELECOM devices:
282 - BM084 Bluetooth Mouse 282 - BM084 Bluetooth Mouse
283 - DEFT Trackball (Wired and wireless) 283 - DEFT Trackball (Wired and wireless)
284 - HUGE Trackball (Wired and wireless)
284 285
285config HID_ELO 286config HID_ELO
286 tristate "ELO USB 4000/4500 touchscreen" 287 tristate "ELO USB 4000/4500 touchscreen"
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 9bc91160819b..330ca983828b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2032,6 +2032,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
2032 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, 2032 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
2033 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, 2033 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },
2034 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, 2034 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) },
2035 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) },
2036 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) },
2035#endif 2037#endif
2036#if IS_ENABLED(CONFIG_HID_ELO) 2038#if IS_ENABLED(CONFIG_HID_ELO)
2037 { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, 2039 { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
index e2c7465df69f..54aeea57d209 100644
--- a/drivers/hid/hid-elecom.c
+++ b/drivers/hid/hid-elecom.c
@@ -3,6 +3,7 @@
3 * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com> 3 * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
4 * Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com> 4 * Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
5 * Copyright (c) 2017 Diego Elio Pettenò <flameeyes@flameeyes.eu> 5 * Copyright (c) 2017 Diego Elio Pettenò <flameeyes@flameeyes.eu>
6 * Copyright (c) 2017 Alex Manoussakis <amanou@gnu.org>
6 */ 7 */
7 8
8/* 9/*
@@ -32,9 +33,11 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
32 break; 33 break;
33 case USB_DEVICE_ID_ELECOM_DEFT_WIRED: 34 case USB_DEVICE_ID_ELECOM_DEFT_WIRED:
34 case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS: 35 case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS:
35 /* The DEFT trackball has eight buttons, but its descriptor only 36 case USB_DEVICE_ID_ELECOM_HUGE_WIRED:
36 * reports five, disabling the three Fn buttons on the top of 37 case USB_DEVICE_ID_ELECOM_HUGE_WIRELESS:
37 * the mouse. 38 /* The DEFT/HUGE trackball has eight buttons, but its descriptor
39 * only reports five, disabling the three Fn buttons on the top
40 * of the mouse.
38 * 41 *
39 * Apply the following diff to the descriptor: 42 * Apply the following diff to the descriptor:
40 * 43 *
@@ -62,7 +65,7 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
62 * End Collection, End Collection, 65 * End Collection, End Collection,
63 */ 66 */
64 if (*rsize == 213 && rdesc[13] == 5 && rdesc[21] == 5) { 67 if (*rsize == 213 && rdesc[13] == 5 && rdesc[21] == 5) {
65 hid_info(hdev, "Fixing up Elecom DEFT Fn buttons\n"); 68 hid_info(hdev, "Fixing up Elecom DEFT/HUGE Fn buttons\n");
66 rdesc[13] = 8; /* Button/Variable Report Count */ 69 rdesc[13] = 8; /* Button/Variable Report Count */
67 rdesc[21] = 8; /* Button/Variable Usage Maximum */ 70 rdesc[21] = 8; /* Button/Variable Usage Maximum */
68 rdesc[29] = 0; /* Button/Constant Report Count */ 71 rdesc[29] = 0; /* Button/Constant Report Count */
@@ -76,6 +79,8 @@ static const struct hid_device_id elecom_devices[] = {
76 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, 79 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
77 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) }, 80 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },
78 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) }, 81 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) },
82 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRED) },
83 { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_HUGE_WIRELESS) },
79 { } 84 { }
80}; 85};
81MODULE_DEVICE_TABLE(hid, elecom_devices); 86MODULE_DEVICE_TABLE(hid, elecom_devices);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index a98919199858..be2e005c3c51 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -368,6 +368,8 @@
368#define USB_DEVICE_ID_ELECOM_BM084 0x0061 368#define USB_DEVICE_ID_ELECOM_BM084 0x0061
369#define USB_DEVICE_ID_ELECOM_DEFT_WIRED 0x00fe 369#define USB_DEVICE_ID_ELECOM_DEFT_WIRED 0x00fe
370#define USB_DEVICE_ID_ELECOM_DEFT_WIRELESS 0x00ff 370#define USB_DEVICE_ID_ELECOM_DEFT_WIRELESS 0x00ff
371#define USB_DEVICE_ID_ELECOM_HUGE_WIRED 0x010c
372#define USB_DEVICE_ID_ELECOM_HUGE_WIRELESS 0x010d
371 373
372#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 374#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34
373#define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004 375#define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 089bad8a9a21..045b5da9b992 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -975,6 +975,8 @@ static int usbhid_parse(struct hid_device *hid)
975 unsigned int rsize = 0; 975 unsigned int rsize = 0;
976 char *rdesc; 976 char *rdesc;
977 int ret, n; 977 int ret, n;
978 int num_descriptors;
979 size_t offset = offsetof(struct hid_descriptor, desc);
978 980
979 quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), 981 quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
980 le16_to_cpu(dev->descriptor.idProduct)); 982 le16_to_cpu(dev->descriptor.idProduct));
@@ -997,10 +999,18 @@ static int usbhid_parse(struct hid_device *hid)
997 return -ENODEV; 999 return -ENODEV;
998 } 1000 }
999 1001
1002 if (hdesc->bLength < sizeof(struct hid_descriptor)) {
1003 dbg_hid("hid descriptor is too short\n");
1004 return -EINVAL;
1005 }
1006
1000 hid->version = le16_to_cpu(hdesc->bcdHID); 1007 hid->version = le16_to_cpu(hdesc->bcdHID);
1001 hid->country = hdesc->bCountryCode; 1008 hid->country = hdesc->bCountryCode;
1002 1009
1003 for (n = 0; n < hdesc->bNumDescriptors; n++) 1010 num_descriptors = min_t(int, hdesc->bNumDescriptors,
1011 (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
1012
1013 for (n = 0; n < num_descriptors; n++)
1004 if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT) 1014 if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
1005 rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength); 1015 rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
1006 1016