aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2014-04-17 16:22:09 -0400
committerJiri Kosina <jkosina@suse.cz>2014-05-20 10:39:00 -0400
commit1b15d2e5b8077670b1e6a33250a0d9577efff4a5 (patch)
treece5ca1f217c59a604ea6378afc68710d65c4f5de /drivers/hid
parent825747bb85634a2a7b7dce4e373831e211ab1644 (diff)
HID: core: fix validation of report id 0
Some drivers use the first HID report in the list instead of using an index. In these cases, validation uses ID 0, which was supposed to mean "first known report". This fixes the problem, which was causing at least the lgff family of devices to stop working since hid_validate_values was being called with ID 0, but the devices used single numbered IDs for their reports: 0x05, 0x01, /* Usage Page (Desktop), */ 0x09, 0x05, /* Usage (Gamepad), */ 0xA1, 0x01, /* Collection (Application), */ 0xA1, 0x02, /* Collection (Logical), */ 0x85, 0x01, /* Report ID (1), */ ... Cc: stable@vger.kernel.org Reported-by: Simon Wood <simon@mungewell.org> Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index da52279de939..a5c7927c9bd2 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -842,7 +842,17 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
842 * ->numbered being checked, which may not always be the case when 842 * ->numbered being checked, which may not always be the case when
843 * drivers go to access report values. 843 * drivers go to access report values.
844 */ 844 */
845 report = hid->report_enum[type].report_id_hash[id]; 845 if (id == 0) {
846 /*
847 * Validating on id 0 means we should examine the first
848 * report in the list.
849 */
850 report = list_entry(
851 hid->report_enum[type].report_list.next,
852 struct hid_report, list);
853 } else {
854 report = hid->report_enum[type].report_id_hash[id];
855 }
846 if (!report) { 856 if (!report) {
847 hid_err(hid, "missing %s %u\n", hid_report_names[type], id); 857 hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
848 return NULL; 858 return NULL;