HID: core: do not reject devices when they declare too many usages
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>
Fri, 24 Jul 2015 16:02:22 +0000 (12:02 -0400)
committerJiri Kosina <jkosina@suse.com>
Mon, 27 Jul 2015 12:41:30 +0000 (14:41 +0200)
Some device present proprietary collections with a usage min of 0x00 and
a usage max of 0xffff. hid-core currently reject them while most of the
time this is harmless.
Let's ignore the exceeding usages, and hope for the best.

Reported-by: Simon Wörner <mail@simon-woerner.de>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/hid-core.c

index 157c627750535e8943769e3078de068e4f1c7a47..b403fe2c5cbe122442e5898a8788dd5f1094d099 100644 (file)
@@ -427,6 +427,7 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
 {
        __u32 data;
        unsigned n;
+       __u32 count;
 
        data = item_udata(item);
 
@@ -490,6 +491,24 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
                if (item->size <= 2)
                        data = (parser->global.usage_page << 16) + data;
 
+               count = data - parser->local.usage_minimum;
+               if (count + parser->local.usage_index >= HID_MAX_USAGES) {
+                       /*
+                        * We do not warn if the name is not set, we are
+                        * actually pre-scanning the device.
+                        */
+                       if (dev_name(&parser->device->dev))
+                               hid_warn(parser->device,
+                                        "ignoring exceeding usage max\n");
+                       data = HID_MAX_USAGES - parser->local.usage_index +
+                               parser->local.usage_minimum - 1;
+                       if (data <= 0) {
+                               hid_err(parser->device,
+                                       "no more usage index available\n");
+                               return -1;
+                       }
+               }
+
                for (n = parser->local.usage_minimum; n <= data; n++)
                        if (hid_add_usage(parser, n)) {
                                dbg_hid("hid_add_usage failed\n");
This page took 0.028454 seconds and 5 git commands to generate.