diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2015-07-24 12:02:22 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.com> | 2015-07-27 14:41:30 +0200 |
commit | ba53219809f4b3a08f21600a0f3b675620d518bc (patch) | |
tree | c2fe0808f9918180d534a085f5591d5374032669 /drivers/hid | |
parent | 3eb4351af42bd8b6de20daab07b204a85c35248f (diff) | |
download | blackbird-op-linux-ba53219809f4b3a08f21600a0f3b675620d518bc.tar.gz blackbird-op-linux-ba53219809f4b3a08f21600a0f3b675620d518bc.zip |
HID: core: do not reject devices when they declare too many usages
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>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-core.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 157c62775053..b403fe2c5cbe 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -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"); |