]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 10 Jan 2015 05:18:48 +0000 (21:18 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 10 Jan 2015 05:18:48 +0000 (21:18 -0800)
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

drivers/hid/Kconfig
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hid-kye.c
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-roccat-pyra.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/usbhid/hid-quirks.c

index 230b6f887cd86e9b4d3d4bf625166c878d5524ed..dfdc26970022998adfb951f50baacb0e4df38474 100644 (file)
@@ -27,7 +27,8 @@ if HID
 
 config HID_BATTERY_STRENGTH
        bool "Battery level reporting for HID devices"
-       depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY
+       depends on HID
+       select POWER_SUPPLY
        default n
        ---help---
        This option adds support of reporting battery strength (for HID devices
index c3d0ac1a0988096eaacbe8063b354399b6a85e14..8b638792cb43c426c2e4fffb0bb594e76617f554 100644 (file)
@@ -1805,6 +1805,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
index 7460f3402298c2e1925059a1ef5cbf669e9d381b..9243359c18219ab75c5e47bda83ed44f3d322f05 100644 (file)
 #define USB_DEVICE_ID_KYE_GPEN_560     0x5003
 #define USB_DEVICE_ID_KYE_EASYPEN_I405X        0x5010
 #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X       0x5011
+#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2     0x501a
 #define USB_DEVICE_ID_KYE_EASYPEN_M610X        0x5013
 
 #define USB_VENDOR_ID_LABTEC           0x1020
index e0a0f06ac5ef6168c8fcdd5c2462df3f3130c941..9505605b6e22a72b29661d568aa6fe4dcaa32643 100644 (file)
@@ -311,6 +311,9 @@ static const struct hid_device_id hid_battery_quirks[] = {
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
                               USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
          HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+                              USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
+         HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
                USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
          HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
index b92bf01a1ae8122f486ea333288558f082162f5d..158fcf577fae570d331a37c46d650a151141c19c 100644 (file)
@@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
                }
                break;
        case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
+       case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
                if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) {
                        rdesc = mousepen_i608x_rdesc_fixed;
                        *rsize = sizeof(mousepen_i608x_rdesc_fixed);
@@ -415,6 +416,7 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id)
        switch (id->product) {
        case USB_DEVICE_ID_KYE_EASYPEN_I405X:
        case USB_DEVICE_ID_KYE_MOUSEPEN_I608X:
+       case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2:
        case USB_DEVICE_ID_KYE_EASYPEN_M610X:
                ret = kye_tablet_enable(hdev);
                if (ret) {
@@ -445,6 +447,8 @@ static const struct hid_device_id kye_devices[] = {
                                USB_DEVICE_ID_KYE_EASYPEN_I405X) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
                                USB_DEVICE_ID_KYE_MOUSEPEN_I608X) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
+                               USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
                                USB_DEVICE_ID_KYE_EASYPEN_M610X) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE,
index c917ab61aafa6156b433ed3148a31384ac6d4292..5bc6d80d5be79f465f3cbbb686c471db6162eb63 100644 (file)
@@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev,
 
        switch (data[0]) {
        case REPORT_ID_DJ_SHORT:
+               if (size != DJREPORT_SHORT_LENGTH) {
+                       dev_err(&hdev->dev, "DJ report of bad size (%d)", size);
+                       return false;
+               }
                return logi_dj_dj_event(hdev, report, data, size);
        case REPORT_ID_HIDPP_SHORT:
-               /* intentional fallthrough */
+               if (size != HIDPP_REPORT_SHORT_LENGTH) {
+                       dev_err(&hdev->dev,
+                               "Short HID++ report of bad size (%d)", size);
+                       return false;
+               }
+               return logi_dj_hidpp_event(hdev, report, data, size);
        case REPORT_ID_HIDPP_LONG:
+               if (size != HIDPP_REPORT_LONG_LENGTH) {
+                       dev_err(&hdev->dev,
+                               "Long HID++ report of bad size (%d)", size);
+                       return false;
+               }
                return logi_dj_hidpp_event(hdev, report, data, size);
        }
 
index 2f420c0b6609b1f197a15be182d07102323b3973..a93cefe0e522e66fe670a28a269f13da9ff25d5d 100644 (file)
@@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
                (report->rap.sub_id == 0x41);
 }
 
+/**
+ * hidpp_prefix_name() prefixes the current given name with "Logitech ".
+ */
+static void hidpp_prefix_name(char **name, int name_length)
+{
+#define PREFIX_LENGTH 9 /* "Logitech " */
+
+       int new_length;
+       char *new_name;
+
+       if (name_length > PREFIX_LENGTH &&
+           strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0)
+               /* The prefix has is already in the name */
+               return;
+
+       new_length = PREFIX_LENGTH + name_length;
+       new_name = kzalloc(new_length, GFP_KERNEL);
+       if (!new_name)
+               return;
+
+       snprintf(new_name, new_length, "Logitech %s", *name);
+
+       kfree(*name);
+
+       *name = new_name;
+}
+
 /* -------------------------------------------------------------------------- */
 /* HIDP++ 1.0 commands                                                        */
 /* -------------------------------------------------------------------------- */
@@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)
                return NULL;
 
        memcpy(name, &response.rap.params[2], len);
+
+       /* include the terminating '\0' */
+       hidpp_prefix_name(&name, len + 1);
+
        return name;
 }
 
@@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp)
                index += ret;
        }
 
+       /* include the terminating '\0' */
+       hidpp_prefix_name(&name, __name_length + 1);
+
        return name;
 }
 
@@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size)
 
        switch (data[0]) {
        case 0x02:
+               if (size < 2) {
+                       hid_err(hdev, "Received HID report of bad size (%d)",
+                               size);
+                       return 1;
+               }
                if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) {
                        input_event(wd->input, EV_KEY, BTN_LEFT,
                                        !!(data[1] & 0x01));
                        input_event(wd->input, EV_KEY, BTN_RIGHT,
                                        !!(data[1] & 0x02));
                        input_sync(wd->input);
+                       return 0;
                } else {
                        if (size < 21)
                                return 1;
                        return wtp_mouse_raw_xy_event(hidpp, &data[7]);
                }
        case REPORT_ID_HIDPP_LONG:
+               /* size is already checked in hidpp_raw_event. */
                if ((report->fap.feature_index != wd->mt_feature_index) ||
                    (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY))
                        return 1;
index 1a07e07d99a06c8972a2d80b8fefa8aa4f4b3848..47d7e74231e5a3245461eb5f34a3acecc5bd67d1 100644 (file)
@@ -35,6 +35,8 @@ static struct class *pyra_class;
 static void profile_activated(struct pyra_device *pyra,
                unsigned int new_profile)
 {
+       if (new_profile >= ARRAY_SIZE(pyra->profile_settings))
+               return;
        pyra->actual_profile = new_profile;
        pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
 }
@@ -257,9 +259,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp,
        if (off != 0 || count != PYRA_SIZE_SETTINGS)
                return -EINVAL;
 
-       mutex_lock(&pyra->pyra_lock);
-
        settings = (struct pyra_settings const *)buf;
+       if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings))
+               return -EINVAL;
+
+       mutex_lock(&pyra->pyra_lock);
 
        retval = pyra_set_settings(usb_dev, settings);
        if (retval) {
index d32037cbf9db5e3bf9b1f4d96a3f8c98259a65a5..d43e967e75339ec7972e734e284c4356e31a4e38 100644 (file)
@@ -706,12 +706,7 @@ static int i2c_hid_start(struct hid_device *hid)
 
 static void i2c_hid_stop(struct hid_device *hid)
 {
-       struct i2c_client *client = hid->driver_data;
-       struct i2c_hid *ihid = i2c_get_clientdata(client);
-
        hid->claimed = 0;
-
-       i2c_hid_free_buffers(ihid);
 }
 
 static int i2c_hid_open(struct hid_device *hid)
index dc89be90b35e80f7d14d5dcaa71dda082c8ab84b..b27b3d33ebab02b9afb7d9fc9dad2e99b31afb14 100644 (file)
@@ -124,6 +124,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
+       { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS },