From: Greg Kroah-Hartman Date: Fri, 27 Sep 2013 21:11:33 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.98~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=51ce0ece36a8d13753b1e3e7bdc89ee000d0789b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: hid-provide-a-helper-for-validating-hid-reports.patch hid-zeroplus-validate-output-report-details.patch --- 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 index 00000000000..f3b74fdbe43 --- /dev/null +++ b/queue-3.0/hid-provide-a-helper-for-validating-hid-reports.patch @@ -0,0 +1,104 @@ +From 331415ff16a12147d57d5c953f3a961b7ede348b Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Wed, 11 Sep 2013 21:56:50 +0200 +Subject: HID: provide a helper for validating hid reports + +From: Kees Cook + +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 +Reviewed-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..900d5d233f2 --- /dev/null +++ b/queue-3.0/hid-zeroplus-validate-output-report-details.patch @@ -0,0 +1,58 @@ +From 78214e81a1bf43740ce89bb5efda78eac2f8ef83 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Wed, 11 Sep 2013 21:56:51 +0200 +Subject: HID: zeroplus: validate output report details + +From: Kees Cook + +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 +Reviewed-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-3.0/series b/queue-3.0/series index 521cbcc1dd8..ec141204c54 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -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