Home / exploitsPDF  

Linux HID security flaws

Posted on 01 September 2013

<pre> I've found several issues in the Linux HID code. They are making their way into the Linux kernel via the linux-input tree now: http://marc.info/?l=linux-input&amp;m=137772180514608&amp;w=1 0001-HID-validate-HID-report-id-size.patch Signed-off-by: Kees Cook &lt;keescook@chromium.org&gt; Cc: stable@kernel.org --- drivers/hid/hid-core.c | 10 +++++++--- include/linux/hid.h | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 36668d1..5ea7d51 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -63,6 +63,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, struct hid_report_enum *report_enum = device-&gt;report_enum + type; struct hid_report *report; + if (id &gt;= HID_MAX_IDS) + return NULL; if (report_enum-&gt;report_id_hash[id]) return report_enum-&gt;report_id_hash[id]; @@ -404,8 +406,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_REPORT_ID: parser-&gt;global.report_id = item_udata(item); - if (parser-&gt;global.report_id == 0) { - hid_err(parser-&gt;device, &quot;report_id 0 is invalid &quot;); + if (parser-&gt;global.report_id == 0 || + parser-&gt;global.report_id &gt;= HID_MAX_IDS) { + hid_err(parser-&gt;device, &quot;report_id %u is invalid &quot;, + parser-&gt;global.report_id); return -1; } return 0; @@ -575,7 +579,7 @@ static void hid_close_report(struct hid_device *device) for (i = 0; i &lt; HID_REPORT_TYPES; i++) { struct hid_report_enum *report_enum = device-&gt;report_enum + i; - for (j = 0; j &lt; 256; j++) { + for (j = 0; j &lt; HID_MAX_IDS; j++) { struct hid_report *report = report_enum-&gt;report_id_hash[j]; if (report) hid_free_report(report); diff --git a/include/linux/hid.h b/include/linux/hid.h index 0c48991..ff545cc 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -393,10 +393,12 @@ struct hid_report { struct hid_device *device; /* associated device */ }; +#define HID_MAX_IDS 256 + struct hid_report_enum { unsigned numbered; struct list_head report_list; - struct hid_report *report_id_hash[256]; + struct hid_report *report_id_hash[HID_MAX_IDS]; }; #define HID_REPORT_TYPES 3 CVE-2013-2888 Requires CONFIG_HID Memory write via arbitrary heap array index. This is the most serious, IMO, as it allows (on 32-bit) access to the entire memory range (the index is unsigned 32 bit). This is mitigated slightly by the fact that the starting address is at an &quot;unknown&quot; location on the heap, and that the value written is an &quot;arbitrary&quot; kernel pointer. Still, this could almost certainly be turned into full kernel execution given enough study. http://marc.info/?l=linux-input&amp;m=137772181214612&amp;w=1 0002-HID-provide-a-helper-for-validating-hid-reports.patch Routine that many of the driver fixes use to verify their report sanity. http://marc.info/?l=linux-input&amp;m=137772182014614&amp;w=1 0003-HID-zeroplus-validate-output-report-details.patch CVE-2013-2889 Requires CONFIG_HID_ZEROPLUS Small past-end-of-heap-alloc zeroing. http://marc.info/?l=linux-input&amp;m=137772182814616&amp;w=1 0004-HID-sony-validate-HID-output-report-details.patch CVE-2013-2890 Requires CONFIG_HID_SONY Small past-end-of-heap-alloc zeroing http://marc.info/?l=linux-input&amp;m=137772184614622&amp;w=1 0005-HID-steelseries-validate-output-report-details.patch CVE-2013-2891 Requires CONFIG_HID_STEELSERIES 16 byte past-end-of-heap-alloc zeroing http://marc.info/?l=linux-input&amp;m=137772185414625&amp;w=1 0006-HID-pantherlord-validate-output-report-details.patch CVE-2013-2892 Requires CONFIG_HID_PANTHERLORD Small past-end-of-heap-alloc zeroing http://marc.info/?l=linux-input&amp;m=137772186714627&amp;w=1 0007-HID-LG-validate-HID-output-report-details.patch CVE-2013-2893 Requires CONFIG_LOGITECH_FF or CONFIG_LOGIG940_FF or CONFIG_LOGIWHEELS_FF Userspace-assisted small past-end-of-heap-alloc zeroing http://marc.info/?l=linux-input&amp;m=137772187514628&amp;w=1 0008-HID-lenovo-tpkbd-validate-output-report-details.patch CVE-2013-2894 Requires CONFIG_HID_LENOVO_TPKBD Small past-end-of-heap-alloc zeroing http://marc.info/?l=linux-input&amp;m=137772188314631&amp;w=1 0009-HID-logitech-dj-validate-output-report-details.patch CVE-2013-2895 Requires CONFIG_HID_LOGITECH_DJ Can leak up to 12K of kernel memory contents to device, or NULL deref Oops DoS http://marc.info/?l=linux-input&amp;m=137772189314633&amp;w=1 0010-HID-ntrig-validate-feature-report-details.patch CVE-2013-2896 Requires CONFIG_HID_NTRIG Triggers NULL deref Oops DoS http://marc.info/?l=linux-input&amp;m=137772190214635&amp;w=1 0011-HID-multitouch-validate-feature-report-details.patch CVE-2013-2897 Requires CONFIG_HID_MULTITOUCH Slightly flexible heap overwrite with static value 0x2, or NULL deref Oops DoS http://marc.info/?l=linux-input&amp;m=137772191114645&amp;w=1 0012-HID-sensor-hub-validate-feature-report-details.patch CVE-2013-2898 Requires CONFIG_HID_SENSOR_HUB Potential kernel caller confusion via past-end-of-heap-allocation read http://marc.info/?l=linux-input&amp;m=137772191714649&amp;w=1 0013-HID-picolcd_core-validate-output-report-details.patch CVE-2013-2899 Requires CONFIG_HID_PICOLCD Userspace-assisted NULL deref Oops DoS http://marc.info/?t=137772196600012&amp;r=1&amp;w=1 0014-HID-check-for-NULL-field-when-setting-values.patch Just a defensive change, since several drivers would have been less vulnerable with this check. -Kees -- Kees Cook Chrome OS Security </pre>

 

TOP