[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-input
Subject: [PATCH 11/14] HID: multitouch: validate feature report details
From: Jiri Kosina <jkosina () suse ! cz>
Date: 2013-08-28 20:31:37
Message-ID: alpine.LNX.2.00.1308282221440.22181 () pobox ! suse ! cz
[Download RAW message or body]
From: Kees Cook <keescook@chromium.org>
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
CVE-2013-2897
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: stable@kernel.org
---
drivers/hid/hid-multitouch.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index cb0e361..2aa275e 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -330,9 +330,18 @@ static void mt_feature_mapping(struct hid_device \
*hdev, break;
}
}
+ /* Ignore if value index is out of bounds. */
+ if (td->inputmode_index < 0 ||
+ td->inputmode_index >= field->report_count) {
+ dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n");
+ td->inputmode = -1;
+ }
break;
case HID_DG_CONTACTMAX:
+ /* Ignore if value count is out of bounds. */
+ if (field->report_count < 1)
+ break;
td->maxcontact_report_id = field->report->id;
td->maxcontacts = field->value[0];
if (!td->maxcontacts &&
@@ -743,15 +752,21 @@ static void mt_touch_report(struct hid_device *hid, \
struct hid_report *report) unsigned count;
int r, n;
+ if (report->maxfield == 0)
+ return;
+
/*
* Includes multi-packet support where subsequent
* packets are sent with zero contactcount.
*/
- if (td->cc_index >= 0) {
- struct hid_field *field = report->field[td->cc_index];
- int value = field->value[td->cc_value_index];
- if (value)
- td->num_expected = value;
+ if (td->cc_index >= 0 && td->cc_index < report->maxfield) {
+ field = report->field[td->cc_index];
+ if (td->cc_value_index >= 0 &&
+ td->cc_value_index < field->report_count) {
+ int value = field->value[td->cc_value_index];
+ if (value)
+ td->num_expected = value;
+ }
}
for (r = 0; r < report->maxfield; r++) {
--
Jiri Kosina
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic