Skip to content

Commit 8821f5d

Browse files
bentissJiri Kosina
authored andcommitted
HID: multitouch: validate indexes details
When working on report indexes, always validate that they are in bounds. Without this, a HID device could report a malicious feature report that could trick the driver into a heap overflow: [ 634.885003] usb 1-1: New USB device found, idVendor=0596, idProduct=0500 ... [ 676.469629] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten Note that we need to change the indexes from s8 to s16 as they can be between -1 and 255. CVE-2013-2897 Cc: [email protected] Signed-off-by: Benjamin Tissoires <[email protected]> Acked-by: Kees Cook <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 297502a commit 8821f5d

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

drivers/hid/hid-multitouch.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ struct mt_device {
101101
unsigned last_slot_field; /* the last field of a slot */
102102
unsigned mt_report_id; /* the report ID of the multitouch device */
103103
unsigned pen_report_id; /* the report ID of the pen device */
104-
__s8 inputmode; /* InputMode HID feature, -1 if non-existent */
105-
__s8 inputmode_index; /* InputMode HID feature index in the report */
106-
__s8 maxcontact_report_id; /* Maximum Contact Number HID feature,
104+
__s16 inputmode; /* InputMode HID feature, -1 if non-existent */
105+
__s16 inputmode_index; /* InputMode HID feature index in the report */
106+
__s16 maxcontact_report_id; /* Maximum Contact Number HID feature,
107107
-1 if non-existent */
108108
__u8 num_received; /* how many contacts we received */
109109
__u8 num_expected; /* expected last contact index */
@@ -312,20 +312,18 @@ static void mt_feature_mapping(struct hid_device *hdev,
312312
struct hid_field *field, struct hid_usage *usage)
313313
{
314314
struct mt_device *td = hid_get_drvdata(hdev);
315-
int i;
316315

317316
switch (usage->hid) {
318317
case HID_DG_INPUTMODE:
319-
td->inputmode = field->report->id;
320-
td->inputmode_index = 0; /* has to be updated below */
321-
322-
for (i=0; i < field->maxusage; i++) {
323-
if (field->usage[i].hid == usage->hid) {
324-
td->inputmode_index = i;
325-
break;
326-
}
318+
/* Ignore if value index is out of bounds. */
319+
if (usage->usage_index >= field->report_count) {
320+
dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n");
321+
break;
327322
}
328323

324+
td->inputmode = field->report->id;
325+
td->inputmode_index = usage->usage_index;
326+
329327
break;
330328
case HID_DG_CONTACTMAX:
331329
td->maxcontact_report_id = field->report->id;
@@ -511,6 +509,10 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
511509
mt_store_field(usage, td, hi);
512510
return 1;
513511
case HID_DG_CONTACTCOUNT:
512+
/* Ignore if indexes are out of bounds. */
513+
if (field->index >= field->report->maxfield ||
514+
usage->usage_index >= field->report_count)
515+
return 1;
514516
td->cc_index = field->index;
515517
td->cc_value_index = usage->usage_index;
516518
return 1;

0 commit comments

Comments
 (0)