aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2018-07-13 10:13:50 -0400
committerJiri Kosina <jkosina@suse.cz>2018-07-17 09:33:47 -0400
commit08a8a7cf14595f95d5cbb28ef5c15c56a6255fb4 (patch)
tree7b51d919ff29ee607b2229bd69f6a9059975c131 /drivers/hid
parentba6b055e0f3b4ff4942e4ab273260affcfad9bff (diff)
HID: core: do not upper bound the collection stack
Looks like 4 was sufficient until now. However, the Surface Dial needs a stack of 5 and simply fails at probing. Dynamically add HID_COLLECTION_STACK_SIZE to the size of the stack if we hit the upper bound. Checkpatch complains about bare unsigned, so converting those to 'unsigned int' in struct hid_parser Acked-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 3942ee61bd1c..5de6f18c9bf7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -128,9 +128,19 @@ static int open_collection(struct hid_parser *parser, unsigned type)
128 128
129 usage = parser->local.usage[0]; 129 usage = parser->local.usage[0];
130 130
131 if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { 131 if (parser->collection_stack_ptr == parser->collection_stack_size) {
132 hid_err(parser->device, "collection stack overflow\n"); 132 unsigned int *collection_stack;
133 return -EINVAL; 133 unsigned int new_size = parser->collection_stack_size +
134 HID_COLLECTION_STACK_SIZE;
135
136 collection_stack = krealloc(parser->collection_stack,
137 new_size * sizeof(unsigned int),
138 GFP_KERNEL);
139 if (!collection_stack)
140 return -ENOMEM;
141
142 parser->collection_stack = collection_stack;
143 parser->collection_stack_size = new_size;
134 } 144 }
135 145
136 if (parser->device->maxcollection == parser->device->collection_size) { 146 if (parser->device->maxcollection == parser->device->collection_size) {
@@ -840,6 +850,7 @@ static int hid_scan_report(struct hid_device *hid)
840 break; 850 break;
841 } 851 }
842 852
853 kfree(parser->collection_stack);
843 vfree(parser); 854 vfree(parser);
844 return 0; 855 return 0;
845} 856}