Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jikos/hid: HID: zeroing of bytes in output fields is bogus HID: allocate hid_parser in a proper way
This commit is contained in:
commit
6ab27c6bf3
|
@ -26,6 +26,7 @@
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
|
||||||
#include <linux/hid.h>
|
#include <linux/hid.h>
|
||||||
#include <linux/hiddev.h>
|
#include <linux/hiddev.h>
|
||||||
|
@ -654,12 +655,13 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
|
||||||
memcpy(device->rdesc, start, size);
|
memcpy(device->rdesc, start, size);
|
||||||
device->rsize = size;
|
device->rsize = size;
|
||||||
|
|
||||||
if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) {
|
if (!(parser = vmalloc(sizeof(struct hid_parser)))) {
|
||||||
kfree(device->rdesc);
|
kfree(device->rdesc);
|
||||||
kfree(device->collection);
|
kfree(device->collection);
|
||||||
kfree(device);
|
kfree(device);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
memset(parser, 0, sizeof(struct hid_parser));
|
||||||
parser->device = device;
|
parser->device = device;
|
||||||
|
|
||||||
end = start + size;
|
end = start + size;
|
||||||
|
@ -668,7 +670,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
|
||||||
if (item.format != HID_ITEM_FORMAT_SHORT) {
|
if (item.format != HID_ITEM_FORMAT_SHORT) {
|
||||||
dbg("unexpected long global item");
|
dbg("unexpected long global item");
|
||||||
hid_free_device(device);
|
hid_free_device(device);
|
||||||
kfree(parser);
|
vfree(parser);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +678,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
|
||||||
dbg("item %u %u %u %u parsing failed\n",
|
dbg("item %u %u %u %u parsing failed\n",
|
||||||
item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
|
item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
|
||||||
hid_free_device(device);
|
hid_free_device(device);
|
||||||
kfree(parser);
|
vfree(parser);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,23 +686,23 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size)
|
||||||
if (parser->collection_stack_ptr) {
|
if (parser->collection_stack_ptr) {
|
||||||
dbg("unbalanced collection at end of report description");
|
dbg("unbalanced collection at end of report description");
|
||||||
hid_free_device(device);
|
hid_free_device(device);
|
||||||
kfree(parser);
|
vfree(parser);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (parser->local.delimiter_depth) {
|
if (parser->local.delimiter_depth) {
|
||||||
dbg("unbalanced delimiter at end of report description");
|
dbg("unbalanced delimiter at end of report description");
|
||||||
hid_free_device(device);
|
hid_free_device(device);
|
||||||
kfree(parser);
|
vfree(parser);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
kfree(parser);
|
vfree(parser);
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg("item fetching failed at offset %d\n", (int)(end - start));
|
dbg("item fetching failed at offset %d\n", (int)(end - start));
|
||||||
hid_free_device(device);
|
hid_free_device(device);
|
||||||
kfree(parser);
|
vfree(parser);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hid_parse_report);
|
EXPORT_SYMBOL_GPL(hid_parse_report);
|
||||||
|
@ -872,10 +874,6 @@ static void hid_output_field(struct hid_field *field, __u8 *data)
|
||||||
unsigned size = field->report_size;
|
unsigned size = field->report_size;
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
|
||||||
/* make sure the unused bits in the last byte are zeros */
|
|
||||||
if (count > 0 && size > 0)
|
|
||||||
data[(offset+count*size-1)/8] = 0;
|
|
||||||
|
|
||||||
for (n = 0; n < count; n++) {
|
for (n = 0; n < count; n++) {
|
||||||
if (field->logical_minimum < 0) /* signed values */
|
if (field->logical_minimum < 0) /* signed values */
|
||||||
implement(data, offset + n * size, size, s32ton(field->value[n], size));
|
implement(data, offset + n * size, size, s32ton(field->value[n], size));
|
||||||
|
|
Loading…
Reference in New Issue