History

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID updates from Jiri Kosina: "Fixes for CVE-2013-2897, CVE-2013-2895, CVE-2013-2897, CVE-2013-2894, CVE-2013-2893, CVE-2013-2891, CVE-2013-2890, CVE-2013-2889. All the bugs are triggerable only by specially crafted evil-on-purpose HW devices. Fixes by Kees Cook and Benjamin Tissoires" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: HID: lenovo-tpkbd: fix leak if tpkbd_probe_tp fails HID: multitouch: validate indexes details HID: logitech-dj: validate output report details HID: validate feature and input report details HID: lenovo-tpkbd: validate output report details HID: LG: validate HID output report details HID: steelseries: validate output report details HID: sony: validate HID output report details HID: zeroplus: validate output report details HID: provide a helper for validating hid reports

Linus Torvalds committed 13 years ago

Commit 84fca9f2 parents 03e1261 0ccdd9e13 files · +146 −116Browse files

Unified · Split

13 files
  1. drivers/hid/hid-core.c +65 −9
  2. drivers/hid/hid-input.c +10 −1
  3. drivers/hid/hid-lenovo-tpkbd.c +19 −6
  4. drivers/hid/hid-lg2ff.c +3 −16
  5. drivers/hid/hid-lg3ff.c +6 −23
  6. drivers/hid/hid-lg4ff.c +1 −19
  7. drivers/hid/hid-lgff.c +2 −15
  8. drivers/hid/hid-logitech-dj.c +8 −2
  9. drivers/hid/hid-multitouch.c +14 −12
  10. drivers/hid/hid-sony.c +4 −0
  11. drivers/hid/hid-steelseries.c +5 −0
  12. drivers/hid/hid-zpff.c +5 −13
  13. include/linux/hid.h +4 −0
drivers/hid/hid-core.c+65−9
@@ -94,7 +94,6 @@ EXPORT_SYMBOL_GPL(hid_register_report); · 93 unmodified lines
9494 static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values)
9595 {
9696 struct hid_field *field;
97− int i;
9897
9998 if (report->maxfield == HID_MAX_FIELDS) {
10099 hid_err(report->device, "too many fields in report\n");
@@ -113,9 +112,6 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned · 12 unmodified lines
113112 field->value = (s32 *)(field->usage + usages);
114113 field->report = report;
115114
116− for (i = 0; i < usages; i++)
117− field->usage[i].usage_index = i;
118−
119115 return field;
120116 }
121117
@@ -226,9 +222,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign · 104 unmodified lines
226222 {
227223 struct hid_report *report;
228224 struct hid_field *field;
229− int usages;
225+ unsigned usages;
230226 unsigned offset;
231− int i;
227+ unsigned i;
232228
233229 report = hid_register_report(parser->device, report_type, parser->global.report_id);
234230 if (!report) {
@@ -255,7 +251,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign · 20 unmodified lines
255251 if (!parser->local.usage_index) /* Ignore padding fields */
256252 return 0;
257253
258− usages = max_t(int, parser->local.usage_index, parser->global.report_count);
254+ usages = max_t(unsigned, parser->local.usage_index,
255+ parser->global.report_count);
259256
260257 field = hid_register_field(report, usages, parser->global.report_count);
261258 if (!field)
@@ -266,13 +263,14 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign · 4 unmodified lines
266263 field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
267264
268265 for (i = 0; i < usages; i++) {
269− int j = i;
266+ unsigned j = i;
270267 /* Duplicate the last usage we parsed if we have excess values */
271268 if (i >= parser->local.usage_index)
272269 j = parser->local.usage_index - 1;
273270 field->usage[i].hid = parser->local.usage[j];
274271 field->usage[i].collection_index =
275272 parser->local.collection_index[j];
273+ field->usage[i].usage_index = i;
276274 }
277275
278276 field->maxusage = usages;
@@ -801,6 +799,64 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size) · 522 unmodified lines
801799 }
802800 EXPORT_SYMBOL_GPL(hid_parse_report);
803801
802+static const char * const hid_report_names[] = {
803+ "HID_INPUT_REPORT",
804+ "HID_OUTPUT_REPORT",
805+ "HID_FEATURE_REPORT",
806+};
807+/**
808+ * hid_validate_values - validate existing device report's value indexes
809+ *
810+ * @device: hid device
811+ * @type: which report type to examine
812+ * @id: which report ID to examine (0 for first)
813+ * @field_index: which report field to examine
814+ * @report_counts: expected number of values
815+ *
816+ * Validate the number of values in a given field of a given report, after
817+ * parsing.
818+ */
819+struct hid_report *hid_validate_values(struct hid_device *hid,
820+ unsigned int type, unsigned int id,
821+ unsigned int field_index,
822+ unsigned int report_counts)
823+{
824+ struct hid_report *report;
825+
826+ if (type > HID_FEATURE_REPORT) {
827+ hid_err(hid, "invalid HID report type %u\n", type);
828+ return NULL;
829+ }
830+
831+ if (id >= HID_MAX_IDS) {
832+ hid_err(hid, "invalid HID report id %u\n", id);
833+ return NULL;
834+ }
835+
836+ /*
837+ * Explicitly not using hid_get_report() here since it depends on
838+ * ->numbered being checked, which may not always be the case when
839+ * drivers go to access report values.
840+ */
841+ report = hid->report_enum[type].report_id_hash[id];
842+ if (!report) {
843+ hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
844+ return NULL;
845+ }
846+ if (report->maxfield <= field_index) {
847+ hid_err(hid, "not enough fields in %s %u\n",
848+ hid_report_names[type], id);
849+ return NULL;
850+ }
851+ if (report->field[field_index]->report_count < report_counts) {
852+ hid_err(hid, "not enough values in %s %u field %u\n",
853+ hid_report_names[type], id, field_index);
854+ return NULL;
855+ }
856+ return report;
857+}
858+EXPORT_SYMBOL_GPL(hid_validate_values);
859+
804860 /**
805861 * hid_open_report - open a driver-specific device report
806862 *
@@ -1296,7 +1352,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, · 489 unmodified lines
12961352 goto out;
12971353 }
12981354
1299− if (hid->claimed != HID_CLAIMED_HIDRAW) {
1355+ if (hid->claimed != HID_CLAIMED_HIDRAW && report->maxfield) {
13001356 for (a = 0; a < report->maxfield; a++)
13011357 hid_input_field(hid, report->field[a], cdata, interrupt);
13021358 hdrv = hid->driver;
drivers/hid/hid-input.c+10−1
@@ -485,6 +485,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel · 484 unmodified lines
485485 if (field->flags & HID_MAIN_ITEM_CONSTANT)
486486 goto ignore;
487487
488+ /* Ignore if report count is out of bounds. */
489+ if (field->report_count < 1)
490+ goto ignore;
491+
488492 /* only LED usages are supported in output fields */
489493 if (field->report_type == HID_OUTPUT_REPORT &&
490494 (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
@@ -1236,7 +1240,11 @@ static void report_features(struct hid_device *hid) · 745 unmodified lines
12361240
12371241 rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
12381242 list_for_each_entry(rep, &rep_enum->report_list, list)
1239− for (i = 0; i < rep->maxfield; i++)
1243+ for (i = 0; i < rep->maxfield; i++) {
1244+ /* Ignore if report count is out of bounds. */
1245+ if (rep->field[i]->report_count < 1)
1246+ continue;
1247+
12401248 for (j = 0; j < rep->field[i]->maxusage; j++) {
12411249 /* Verify if Battery Strength feature is available */
12421250 hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]);
@@ -1245,6 +1253,7 @@ static void report_features(struct hid_device *hid) · 2 unmodified lines
12451253 drv->feature_mapping(hid, rep->field[i],
12461254 rep->field[i]->usage + j);
12471255 }
1256+ }
12481257 }
12491258
12501259 static struct hid_input *hidinput_allocate(struct hid_device *hid)
drivers/hid/hid-lenovo-tpkbd.c+19−6
@@ -339,7 +339,15 @@ static int tpkbd_probe_tp(struct hid_device *hdev) · 338 unmodified lines
339339 struct tpkbd_data_pointer *data_pointer;
340340 size_t name_sz = strlen(dev_name(dev)) + 16;
341341 char *name_mute, *name_micmute;
342− int ret;
342+ int i, ret;
343+
344+ /* Validate required reports. */
345+ for (i = 0; i < 4; i++) {
346+ if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
347+ return -ENODEV;
348+ }
349+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2))
350+ return -ENODEV;
343351
344352 if (sysfs_create_group(&hdev->dev.kobj,
345353 &tpkbd_attr_group_pointer)) {
@@ -406,22 +414,27 @@ static int tpkbd_probe(struct hid_device *hdev, · 60 unmodified lines
406414 ret = hid_parse(hdev);
407415 if (ret) {
408416 hid_err(hdev, "hid_parse failed\n");
409− goto err_free;
417+ goto err;
410418 }
411419
412420 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
413421 if (ret) {
414422 hid_err(hdev, "hid_hw_start failed\n");
415− goto err_free;
423+ goto err;
416424 }
417425
418426 uhdev = (struct usbhid_device *) hdev->driver_data;
419427
420− if (uhdev->ifnum == 1)
421− return tpkbd_probe_tp(hdev);
428+ if (uhdev->ifnum == 1) {
429+ ret = tpkbd_probe_tp(hdev);
430+ if (ret)
431+ goto err_hid;
432+ }
422433
423434 return 0;
424−err_free:
435+err_hid:
436+ hid_hw_stop(hdev);
437+err:
425438 return ret;
426439 }
427440
drivers/hid/hid-lg2ff.c+3−16
@@ -64,26 +64,13 @@ int lg2ff_init(struct hid_device *hid) · 63 unmodified lines
6464 struct hid_report *report;
6565 struct hid_input *hidinput = list_entry(hid->inputs.next,
6666 struct hid_input, list);
67− struct list_head *report_list =
68− &hid->report_enum[HID_OUTPUT_REPORT].report_list;
6967 struct input_dev *dev = hidinput->input;
7068 int error;
7169
72− if (list_empty(report_list)) {
73− hid_err(hid, "no output report found\n");
70+ /* Check that the report looks ok */
71+ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7);
72+ if (!report)
7473 return -ENODEV;
75− }
76−
77− report = list_entry(report_list->next, struct hid_report, list);
78−
79− if (report->maxfield < 1) {
80− hid_err(hid, "output report is empty\n");
81− return -ENODEV;
82− }
83− if (report->field[0]->report_count < 7) {
84− hid_err(hid, "not enough values in the field\n");
85− return -ENODEV;
86− }
8774
8875 lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
8976 if (!lg2ff)
drivers/hid/hid-lg3ff.c+6−23
@@ -66,10 +66,11 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data, · 65 unmodified lines
6666 int x, y;
6767
6868 /*
69− * Maxusage should always be 63 (maximum fields)
70− * likely a better way to ensure this data is clean
69+ * Available values in the field should always be 63, but we only use up to
70+ * 35. Instead, clear the entire area, however big it is.
7171 */
72− memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage);
72+ memset(report->field[0]->value, 0,
73+ sizeof(__s32) * report->field[0]->report_count);
7374
7475 switch (effect->type) {
7576 case FF_CONSTANT:
@@ -129,32 +130,14 @@ static const signed short ff3_joystick_ac[] = { · 53 unmodified lines
129130 int lg3ff_init(struct hid_device *hid)
130131 {
131132 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
132− struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
133133 struct input_dev *dev = hidinput->input;
134− struct hid_report *report;
135− struct hid_field *field;
136134 const signed short *ff_bits = ff3_joystick_ac;
137135 int error;
138136 int i;
139137
140− /* Find the report to use */
141− if (list_empty(report_list)) {
142− hid_err(hid, "No output report found\n");
143− return -1;
144− }
145−
146138 /* Check that the report looks ok */
147− report = list_entry(report_list->next, struct hid_report, list);
148− if (!report) {
149− hid_err(hid, "NULL output report\n");
150− return -1;
151− }
152−
153− field = report->field[0];
154− if (!field) {
155− hid_err(hid, "NULL field\n");
156− return -1;
157− }
139+ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35))
140+ return -ENODEV;
158141
159142 /* Assume single fixed device G940 */
160143 for (i = 0; ff_bits[i] >= 0; i++)
drivers/hid/hid-lg4ff.c+1−19
@@ -484,34 +484,16 @@ static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cde · 483 unmodified lines
484484 int lg4ff_init(struct hid_device *hid)
485485 {
486486 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
487− struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
488487 struct input_dev *dev = hidinput->input;
489− struct hid_report *report;
490− struct hid_field *field;
491488 struct lg4ff_device_entry *entry;
492489 struct lg_drv_data *drv_data;
493490 struct usb_device_descriptor *udesc;
494491 int error, i, j;
495492 __u16 bcdDevice, rev_maj, rev_min;
496493
497− /* Find the report to use */
498− if (list_empty(report_list)) {
499− hid_err(hid, "No output report found\n");
500− return -1;
501− }
502−
503494 /* Check that the report looks ok */
504− report = list_entry(report_list->next, struct hid_report, list);
505− if (!report) {
506− hid_err(hid, "NULL output report\n");
495+ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7))
507496 return -1;
508− }
509−
510− field = report->field[0];
511− if (!field) {
512− hid_err(hid, "NULL field\n");
513− return -1;
514− }
515497
516498 /* Check what wheel has been connected */
517499 for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) {
drivers/hid/hid-lgff.c+2−15
@@ -128,27 +128,14 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) · 127 unmodified lines
128128 int lgff_init(struct hid_device* hid)
129129 {
130130 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
131− struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
132131 struct input_dev *dev = hidinput->input;
133− struct hid_report *report;
134− struct hid_field *field;
135132 const signed short *ff_bits = ff_joystick;
136133 int error;
137134 int i;
138135
139− /* Find the report to use */
140− if (list_empty(report_list)) {
141− hid_err(hid, "No output report found\n");
142− return -1;
143− }
144−
145136 /* Check that the report looks ok */
146− report = list_entry(report_list->next, struct hid_report, list);
147− field = report->field[0];
148− if (!field) {
149− hid_err(hid, "NULL field\n");
150− return -1;
151− }
137+ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7))
138+ return -ENODEV;
152139
153140 for (i = 0; i < ARRAY_SIZE(devices); i++) {
154141 if (dev->id.vendor == devices[i].idVendor &&
drivers/hid/hid-logitech-dj.c+8−2
@@ -461,7 +461,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, · 460 unmodified lines
461461 struct hid_report *report;
462462 struct hid_report_enum *output_report_enum;
463463 u8 *data = (u8 *)(&dj_report->device_index);
464− int i;
464+ unsigned int i;
465465
466466 output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
467467 report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
@@ -471,7 +471,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, · 3 unmodified lines
471471 return -ENODEV;
472472 }
473473
474− for (i = 0; i < report->field[0]->report_count; i++)
474+ for (i = 0; i < DJREPORT_SHORT_LENGTH - 1; i++)
475475 report->field[0]->value[i] = data[i];
476476
477477 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
@@ -791,6 +791,12 @@ static int logi_dj_probe(struct hid_device *hdev, · 313 unmodified lines
791791 goto hid_parse_fail;
792792 }
793793
794+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, REPORT_ID_DJ_SHORT,
795+ 0, DJREPORT_SHORT_LENGTH - 1)) {
796+ retval = -ENODEV;
797+ goto hid_parse_fail;
798+ }
799+
794800 /* Starts the usb device and connects to upper interfaces hiddev and
795801 * hidraw */
796802 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
drivers/hid/hid-multitouch.c+14−12
@@ -101,9 +101,9 @@ struct mt_device { · 100 unmodified lines
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, · 202 unmodified lines
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, · 179 unmodified lines
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;
drivers/hid/hid-sony.c+4−0
@@ -537,6 +537,10 @@ static int buzz_init(struct hid_device *hdev) · 536 unmodified lines
537537 drv_data = hid_get_drvdata(hdev);
538538 BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
539539
540+ /* Validate expected report characteristics. */
541+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
542+ return -ENODEV;
543+
540544 buzz = kzalloc(sizeof(*buzz), GFP_KERNEL);
541545 if (!buzz) {
542546 hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
drivers/hid/hid-steelseries.c+5−0
@@ -249,6 +249,11 @@ static int steelseries_srws1_probe(struct hid_device *hdev, · 248 unmodified lines
249249 goto err_free;
250250 }
251251
252+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 16)) {
253+ ret = -ENODEV;
254+ goto err_free;
255+ }
256+
252257 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
253258 if (ret) {
254259 hid_err(hdev, "hw start failed\n");
drivers/hid/hid-zpff.c+5−13
@@ -68,21 +68,13 @@ static int zpff_init(struct hid_device *hid) · 67 unmodified lines
6868 struct hid_report *report;
6969 struct hid_input *hidinput = list_entry(hid->inputs.next,
7070 struct hid_input, list);
71− struct list_head *report_list =
72− &hid->report_enum[HID_OUTPUT_REPORT].report_list;
7371 struct input_dev *dev = hidinput->input;
74− int error;
72+ int i, error;
7573
76− if (list_empty(report_list)) {
77− hid_err(hid, "no output report found\n");
78− return -ENODEV;
79− }
80−
81− report = list_entry(report_list->next, struct hid_report, list);
82−
83− if (report->maxfield < 4) {
84− hid_err(hid, "not enough fields in report\n");
85− return -ENODEV;
74+ for (i = 0; i < 4; i++) {
75+ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1);
76+ if (!report)
77+ return -ENODEV;
8678 }
8779
8880 zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
include/linux/hid.h+4−0
@@ -756,6 +756,10 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags); · 755 unmodified lines
756756 struct hid_device *hid_allocate_device(void);
757757 struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
758758 int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
759+struct hid_report *hid_validate_values(struct hid_device *hid,
760+ unsigned int type, unsigned int id,
761+ unsigned int field_index,
762+ unsigned int report_counts);
759763 int hid_open_report(struct hid_device *device);
760764 int hid_check_keys_pressed(struct hid_device *hid);
761765 int hid_connect(struct hid_device *hid, unsigned int connect_mask);