Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: make arrays usage and value to be the same

The HID subsystem allows an "HID report field" to have a different
number of "values" and "usages" when it is allocated. When a field
struct is created, the size of the usage array is guaranteed to be at
least as large as the values array, but it may be larger. This leads to
a potential out-of-bounds write in
__hidinput_change_resolution_multipliers() and an out-of-bounds read in
hidinput_count_leds().

To fix this, let's make sure that both the usage and value arrays are
the same size.

Cc: stable@vger.kernel.org
Signed-off-by: Will McVicker <willmcvicker@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Will McVicker and committed by
Jiri Kosina
ed9be64e a0312af1

+3 -3
+3 -3
drivers/hid/hid-core.c
··· 90 90 * Register a new field for this report. 91 91 */ 92 92 93 - static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) 93 + static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages) 94 94 { 95 95 struct hid_field *field; 96 96 ··· 101 101 102 102 field = kzalloc((sizeof(struct hid_field) + 103 103 usages * sizeof(struct hid_usage) + 104 - values * sizeof(unsigned)), GFP_KERNEL); 104 + usages * sizeof(unsigned)), GFP_KERNEL); 105 105 if (!field) 106 106 return NULL; 107 107 ··· 300 300 usages = max_t(unsigned, parser->local.usage_index, 301 301 parser->global.report_count); 302 302 303 - field = hid_register_field(report, usages, parser->global.report_count); 303 + field = hid_register_field(report, usages); 304 304 if (!field) 305 305 return 0; 306 306