Commit 28023d2a8e9121b1b06c3b46e523c3c7a3e8b530

Authored by Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID updates from Jiri Kosina:

 - bounds checking fixes in logitech and roccat drivers, from Peter Wu
   and Dan Carpenter

 - double-kfree fix in i2c-hid driver on bus shutdown, from Mika
   Westerberg

 - a couple of various small driver fixes

 - a few device id additions

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: roccat: potential out of bounds in pyra_sysfs_write_settings()
  HID: Add a new id 0x501a for Genius MousePen i608X
  HID: logitech-hidpp: prefix the name with "Logitech"
  HID: logitech-hidpp: avoid unintended fall-through
  HID: Allow HID_BATTERY_STRENGTH to be enabled
  HID: i2c-hid: Do not free buffers in i2c_hid_stop()
  HID: add battery quirk for USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO keyboard
  HID: logitech-hidpp: check WTP report length
  HID: logitech-dj: check report length

Showing 10 changed files Side-by-side Diff

... ... @@ -27,7 +27,8 @@
27 27  
28 28 config HID_BATTERY_STRENGTH
29 29 bool "Battery level reporting for HID devices"
30   - depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
  30 + depends on HID
  31 + select POWER_SUPPLY
31 32 default n
32 33 ---help---
33 34 This option adds support of reporting battery strength (for HID devices
drivers/hid/hid-core.c
... ... @@ -1805,6 +1805,7 @@
1805 1805 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
1806 1806 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
1807 1807 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
  1808 + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
1808 1809 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
1809 1810 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
1810 1811 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
drivers/hid/hid-ids.h
... ... @@ -526,6 +526,7 @@
526 526 #define USB_DEVICE_ID_KYE_GPEN_560 0x5003
527 527 #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010
528 528 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011
  529 +#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2 0x501a
529 530 #define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013
530 531  
531 532 #define USB_VENDOR_ID_LABTEC 0x1020
drivers/hid/hid-input.c
... ... @@ -312,6 +312,9 @@
312 312 USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
313 313 HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
314 314 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
  315 + USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
  316 + HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
  317 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
315 318 USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
316 319 HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
317 320 {}
drivers/hid/hid-kye.c
... ... @@ -323,6 +323,7 @@
323 323 }
324 324 break;
325 325 case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
  326 + case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
326 327 if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) {
327 328 rdesc = mousepen_i608x_rdesc_fixed;
328 329 *rsize = sizeof(mousepen_i608x_rdesc_fixed);
... ... @@ -415,6 +416,7 @@
415 416 switch (id->product) {
416 417 case USB_DEVICE_ID_KYE_EASYPEN_I405X:
417 418 case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
  419 + case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
418 420 case USB_DEVICE_ID_KYE_EASYPEN_M610X:
419 421 ret = kye_tablet_enable(hdev);
420 422 if (ret) {
... ... @@ -445,6 +447,8 @@
445 447 USB_DEVICE_ID_KYE_EASYPEN_I405X) },
446 448 { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
447 449 USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
  450 + { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
  451 + USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
448 452 { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
449 453 USB_DEVICE_ID_KYE_EASYPEN_M610X) },
450 454 { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
drivers/hid/hid-logitech-dj.c
... ... @@ -962,10 +962,24 @@
962 962  
963 963 switch (data[0]) {
964 964 case REPORT_ID_DJ_SHORT:
  965 + if (size != DJREPORT_SHORT_LENGTH) {
  966 + dev_err(&hdev->dev, "DJ report of bad size (%d)", size);
  967 + return false;
  968 + }
965 969 return logi_dj_dj_event(hdev, report, data, size);
966 970 case REPORT_ID_HIDPP_SHORT:
967   - /* intentional fallthrough */
  971 + if (size != HIDPP_REPORT_SHORT_LENGTH) {
  972 + dev_err(&hdev->dev,
  973 + "Short HID++ report of bad size (%d)", size);
  974 + return false;
  975 + }
  976 + return logi_dj_hidpp_event(hdev, report, data, size);
968 977 case REPORT_ID_HIDPP_LONG:
  978 + if (size != HIDPP_REPORT_LONG_LENGTH) {
  979 + dev_err(&hdev->dev,
  980 + "Long HID++ report of bad size (%d)", size);
  981 + return false;
  982 + }
969 983 return logi_dj_hidpp_event(hdev, report, data, size);
970 984 }
971 985  
drivers/hid/hid-logitech-hidpp.c
... ... @@ -282,6 +282,33 @@
282 282 (report->rap.sub_id == 0x41);
283 283 }
284 284  
  285 +/**
  286 + * hidpp_prefix_name() prefixes the current given name with "Logitech ".
  287 + */
  288 +static void hidpp_prefix_name(char **name, int name_length)
  289 +{
  290 +#define PREFIX_LENGTH 9 /* "Logitech " */
  291 +
  292 + int new_length;
  293 + char *new_name;
  294 +
  295 + if (name_length > PREFIX_LENGTH &&
  296 + strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0)
  297 + /* The prefix has is already in the name */
  298 + return;
  299 +
  300 + new_length = PREFIX_LENGTH + name_length;
  301 + new_name = kzalloc(new_length, GFP_KERNEL);
  302 + if (!new_name)
  303 + return;
  304 +
  305 + snprintf(new_name, new_length, "Logitech %s", *name);
  306 +
  307 + kfree(*name);
  308 +
  309 + *name = new_name;
  310 +}
  311 +
285 312 /* -------------------------------------------------------------------------- */
286 313 /* HIDP++ 1.0 commands */
287 314 /* -------------------------------------------------------------------------- */
... ... @@ -321,6 +348,10 @@
321 348 return NULL;
322 349  
323 350 memcpy(name, &response.rap.params[2], len);
  351 +
  352 + /* include the terminating '\0' */
  353 + hidpp_prefix_name(&name, len + 1);
  354 +
324 355 return name;
325 356 }
326 357  
... ... @@ -498,6 +529,9 @@
498 529 index += ret;
499 530 }
500 531  
  532 + /* include the terminating '\0' */
  533 + hidpp_prefix_name(&name, __name_length + 1);
  534 +
501 535 return name;
502 536 }
503 537  
504 538  
505 539  
... ... @@ -794,18 +828,25 @@
794 828  
795 829 switch (data[0]) {
796 830 case 0x02:
  831 + if (size < 2) {
  832 + hid_err(hdev, "Received HID report of bad size (%d)",
  833 + size);
  834 + return 1;
  835 + }
797 836 if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
798 837 input_event(wd->input, EV_KEY, BTN_LEFT,
799 838 !!(data[1] & 0x01));
800 839 input_event(wd->input, EV_KEY, BTN_RIGHT,
801 840 !!(data[1] & 0x02));
802 841 input_sync(wd->input);
  842 + return 0;
803 843 } else {
804 844 if (size < 21)
805 845 return 1;
806 846 return wtp_mouse_raw_xy_event(hidpp, &data[7]);
807 847 }
808 848 case REPORT_ID_HIDPP_LONG:
  849 + /* size is already checked in hidpp_raw_event. */
809 850 if ((report->fap.feature_index != wd->mt_feature_index) ||
810 851 (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
811 852 return 1;
drivers/hid/hid-roccat-pyra.c
... ... @@ -35,6 +35,8 @@
35 35 static void profile_activated(struct pyra_device *pyra,
36 36 unsigned int new_profile)
37 37 {
  38 + if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
  39 + return;
38 40 pyra->actual_profile = new_profile;
39 41 pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
40 42 }
41 43  
... ... @@ -257,9 +259,11 @@
257 259 if (off != 0 || count != PYRA_SIZE_SETTINGS)
258 260 return -EINVAL;
259 261  
260   - mutex_lock(&pyra->pyra_lock);
261   -
262 262 settings = (struct pyra_settings const *)buf;
  263 + if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings))
  264 + return -EINVAL;
  265 +
  266 + mutex_lock(&pyra->pyra_lock);
263 267  
264 268 retval = pyra_set_settings(usb_dev, settings);
265 269 if (retval) {
drivers/hid/i2c-hid/i2c-hid.c
... ... @@ -706,12 +706,7 @@
706 706  
707 707 static void i2c_hid_stop(struct hid_device *hid)
708 708 {
709   - struct i2c_client *client = hid->driver_data;
710   - struct i2c_hid *ihid = i2c_get_clientdata(client);
711   -
712 709 hid->claimed = 0;
713   -
714   - i2c_hid_free_buffers(ihid);
715 710 }
716 711  
717 712 static int i2c_hid_open(struct hid_device *hid)
drivers/hid/usbhid/hid-quirks.c
... ... @@ -124,6 +124,7 @@
124 124 { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
125 125 { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
126 126 { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
  127 + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT },
127 128 { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
128 129 { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
129 130 { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },