Browse Source

HID: core: prevent out-of-bound readings

Plugging a Logitech DJ receiver with KASAN activated raises a bunch of
out-of-bound readings.

The fields are allocated up to MAX_USAGE, meaning that potentially, we do
not have enough fields to fit the incoming values.
Add checks and silence KASAN.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Benjamin Tissoires 9 years ago
parent
commit
50220dead1
1 changed files with 3 additions and 0 deletions
  1. 3 0
      drivers/hid/hid-core.c

+ 3 - 0
drivers/hid/hid-core.c

@@ -1293,6 +1293,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field,
 		/* Ignore report if ErrorRollOver */
 		/* Ignore report if ErrorRollOver */
 		if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
 		if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
 		    value[n] >= min && value[n] <= max &&
 		    value[n] >= min && value[n] <= max &&
+		    value[n] - min < field->maxusage &&
 		    field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
 		    field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
 			goto exit;
 			goto exit;
 	}
 	}
@@ -1305,11 +1306,13 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field,
 		}
 		}
 
 
 		if (field->value[n] >= min && field->value[n] <= max
 		if (field->value[n] >= min && field->value[n] <= max
+			&& field->value[n] - min < field->maxusage
 			&& field->usage[field->value[n] - min].hid
 			&& field->usage[field->value[n] - min].hid
 			&& search(value, field->value[n], count))
 			&& search(value, field->value[n], count))
 				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
 				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
 
 
 		if (value[n] >= min && value[n] <= max
 		if (value[n] >= min && value[n] <= max
+			&& value[n] - min < field->maxusage
 			&& field->usage[value[n] - min].hid
 			&& field->usage[value[n] - min].hid
 			&& search(field->value, value[n], count))
 			&& search(field->value, value[n], count))
 				hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
 				hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);