Commit 6ab27c6bf38d5ff71dafeca77b79e7c284804b75
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
Showing 1 changed file Side-by-side Diff
drivers/hid/hid-core.c
... | ... | @@ -26,6 +26,7 @@ |
26 | 26 | #include <asm/byteorder.h> |
27 | 27 | #include <linux/input.h> |
28 | 28 | #include <linux/wait.h> |
29 | +#include <linux/vmalloc.h> | |
29 | 30 | |
30 | 31 | #include <linux/hid.h> |
31 | 32 | #include <linux/hiddev.h> |
32 | 33 | |
... | ... | @@ -654,12 +655,13 @@ |
654 | 655 | memcpy(device->rdesc, start, size); |
655 | 656 | device->rsize = size; |
656 | 657 | |
657 | - if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) { | |
658 | + if (!(parser = vmalloc(sizeof(struct hid_parser)))) { | |
658 | 659 | kfree(device->rdesc); |
659 | 660 | kfree(device->collection); |
660 | 661 | kfree(device); |
661 | 662 | return NULL; |
662 | 663 | } |
664 | + memset(parser, 0, sizeof(struct hid_parser)); | |
663 | 665 | parser->device = device; |
664 | 666 | |
665 | 667 | end = start + size; |
... | ... | @@ -668,7 +670,7 @@ |
668 | 670 | if (item.format != HID_ITEM_FORMAT_SHORT) { |
669 | 671 | dbg("unexpected long global item"); |
670 | 672 | hid_free_device(device); |
671 | - kfree(parser); | |
673 | + vfree(parser); | |
672 | 674 | return NULL; |
673 | 675 | } |
674 | 676 | |
... | ... | @@ -676,7 +678,7 @@ |
676 | 678 | dbg("item %u %u %u %u parsing failed\n", |
677 | 679 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); |
678 | 680 | hid_free_device(device); |
679 | - kfree(parser); | |
681 | + vfree(parser); | |
680 | 682 | return NULL; |
681 | 683 | } |
682 | 684 | |
683 | 685 | |
684 | 686 | |
685 | 687 | |
... | ... | @@ -684,23 +686,23 @@ |
684 | 686 | if (parser->collection_stack_ptr) { |
685 | 687 | dbg("unbalanced collection at end of report description"); |
686 | 688 | hid_free_device(device); |
687 | - kfree(parser); | |
689 | + vfree(parser); | |
688 | 690 | return NULL; |
689 | 691 | } |
690 | 692 | if (parser->local.delimiter_depth) { |
691 | 693 | dbg("unbalanced delimiter at end of report description"); |
692 | 694 | hid_free_device(device); |
693 | - kfree(parser); | |
695 | + vfree(parser); | |
694 | 696 | return NULL; |
695 | 697 | } |
696 | - kfree(parser); | |
698 | + vfree(parser); | |
697 | 699 | return device; |
698 | 700 | } |
699 | 701 | } |
700 | 702 | |
701 | 703 | dbg("item fetching failed at offset %d\n", (int)(end - start)); |
702 | 704 | hid_free_device(device); |
703 | - kfree(parser); | |
705 | + vfree(parser); | |
704 | 706 | return NULL; |
705 | 707 | } |
706 | 708 | EXPORT_SYMBOL_GPL(hid_parse_report); |
... | ... | @@ -871,10 +873,6 @@ |
871 | 873 | unsigned offset = field->report_offset; |
872 | 874 | unsigned size = field->report_size; |
873 | 875 | unsigned n; |
874 | - | |
875 | - /* make sure the unused bits in the last byte are zeros */ | |
876 | - if (count > 0 && size > 0) | |
877 | - data[(offset+count*size-1)/8] = 0; | |
878 | 876 | |
879 | 877 | for (n = 0; n < count; n++) { |
880 | 878 | if (field->logical_minimum < 0) /* signed values */ |