]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2013 21:11:33 +0000 (14:11 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 27 Sep 2013 21:11:33 +0000 (14:11 -0700)
added patches:
hid-provide-a-helper-for-validating-hid-reports.patch
hid-zeroplus-validate-output-report-details.patch

queue-3.0/hid-provide-a-helper-for-validating-hid-reports.patch [new file with mode: 0644]
queue-3.0/hid-zeroplus-validate-output-report-details.patch [new file with mode: 0644]
queue-3.0/series

diff --git a/queue-3.0/hid-provide-a-helper-for-validating-hid-reports.patch b/queue-3.0/hid-provide-a-helper-for-validating-hid-reports.patch
new file mode 100644 (file)
index 0000000..f3b74fd
--- /dev/null
@@ -0,0 +1,104 @@
+From 331415ff16a12147d57d5c953f3a961b7ede348b Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Wed, 11 Sep 2013 21:56:50 +0200
+Subject: HID: provide a helper for validating hid reports
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 331415ff16a12147d57d5c953f3a961b7ede348b upstream.
+
+Many drivers need to validate the characteristics of their HID report
+during initialization to avoid misusing the reports. This adds a common
+helper to perform validation of the report exisitng, the field existing,
+and the expected number of values within the field.
+
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-core.c |   58 +++++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/hid.h    |    4 +++
+ 2 files changed, 62 insertions(+)
+
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -815,6 +815,64 @@ static int search(__s32 *array, __s32 va
+       return -1;
+ }
++static const char * const hid_report_names[] = {
++      "HID_INPUT_REPORT",
++      "HID_OUTPUT_REPORT",
++      "HID_FEATURE_REPORT",
++};
++/**
++ * hid_validate_values - validate existing device report's value indexes
++ *
++ * @device: hid device
++ * @type: which report type to examine
++ * @id: which report ID to examine (0 for first)
++ * @field_index: which report field to examine
++ * @report_counts: expected number of values
++ *
++ * Validate the number of values in a given field of a given report, after
++ * parsing.
++ */
++struct hid_report *hid_validate_values(struct hid_device *hid,
++                                     unsigned int type, unsigned int id,
++                                     unsigned int field_index,
++                                     unsigned int report_counts)
++{
++      struct hid_report *report;
++
++      if (type > HID_FEATURE_REPORT) {
++              hid_err(hid, "invalid HID report type %u\n", type);
++              return NULL;
++      }
++
++      if (id >= HID_MAX_IDS) {
++              hid_err(hid, "invalid HID report id %u\n", id);
++              return NULL;
++      }
++
++      /*
++       * Explicitly not using hid_get_report() here since it depends on
++       * ->numbered being checked, which may not always be the case when
++       * drivers go to access report values.
++       */
++      report = hid->report_enum[type].report_id_hash[id];
++      if (!report) {
++              hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
++              return NULL;
++      }
++      if (report->maxfield <= field_index) {
++              hid_err(hid, "not enough fields in %s %u\n",
++                      hid_report_names[type], id);
++              return NULL;
++      }
++      if (report->field[field_index]->report_count < report_counts) {
++              hid_err(hid, "not enough values in %s %u field %u\n",
++                      hid_report_names[type], id, field_index);
++              return NULL;
++      }
++      return report;
++}
++EXPORT_SYMBOL_GPL(hid_validate_values);
++
+ /**
+  * hid_match_report - check if driver's raw_event should be called
+  *
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -713,6 +713,10 @@ void hid_output_report(struct hid_report
+ struct hid_device *hid_allocate_device(void);
+ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
+ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
++struct hid_report *hid_validate_values(struct hid_device *hid,
++                                     unsigned int type, unsigned int id,
++                                     unsigned int field_index,
++                                     unsigned int report_counts);
+ int hid_check_keys_pressed(struct hid_device *hid);
+ int hid_connect(struct hid_device *hid, unsigned int connect_mask);
+ void hid_disconnect(struct hid_device *hid);
diff --git a/queue-3.0/hid-zeroplus-validate-output-report-details.patch b/queue-3.0/hid-zeroplus-validate-output-report-details.patch
new file mode 100644 (file)
index 0000000..900d5d2
--- /dev/null
@@ -0,0 +1,58 @@
+From 78214e81a1bf43740ce89bb5efda78eac2f8ef83 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Wed, 11 Sep 2013 21:56:51 +0200
+Subject: HID: zeroplus: validate output report details
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 78214e81a1bf43740ce89bb5efda78eac2f8ef83 upstream.
+
+The zeroplus HID driver was not checking the size of allocated values
+in fields it used. A HID device could send a malicious output report
+that would cause the driver to write beyond the output report allocation
+during initialization, causing a heap overflow:
+
+[ 1442.728680] usb 1-1: New USB device found, idVendor=0c12, idProduct=0005
+...
+[ 1466.243173] BUG kmalloc-192 (Tainted: G        W   ): Redzone overwritten
+
+CVE-2013-2889
+
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-zpff.c |   18 +++++-------------
+ 1 file changed, 5 insertions(+), 13 deletions(-)
+
+--- a/drivers/hid/hid-zpff.c
++++ b/drivers/hid/hid-zpff.c
+@@ -69,21 +69,13 @@ static int zpff_init(struct hid_device *
+       struct hid_report *report;
+       struct hid_input *hidinput = list_entry(hid->inputs.next,
+                                               struct hid_input, list);
+-      struct list_head *report_list =
+-                      &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+       struct input_dev *dev = hidinput->input;
+-      int error;
++      int i, error;
+-      if (list_empty(report_list)) {
+-              hid_err(hid, "no output report found\n");
+-              return -ENODEV;
+-      }
+-
+-      report = list_entry(report_list->next, struct hid_report, list);
+-
+-      if (report->maxfield < 4) {
+-              hid_err(hid, "not enough fields in report\n");
+-              return -ENODEV;
++      for (i = 0; i < 4; i++) {
++              report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1);
++              if (!report)
++                      return -ENODEV;
+       }
+       zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
index 521cbcc1dd8b5f131aa6fd4644e16074edc5cdee..ec141204c54f51ab5a189c25f7c83dcc766c0d43 100644 (file)
@@ -1,3 +1,5 @@
 revert-sctp-fix-call-to-sctp_cmd_process_sack-in.patch
 net-usb-cdc_ether-use-wwan-interface-for-telit-modules.patch
 rt2800-fix-wrong-tx-power-compensation.patch
+hid-provide-a-helper-for-validating-hid-reports.patch
+hid-zeroplus-validate-output-report-details.patch