| From: Alan Stern <stern@rowland.harvard.edu> |
| Date: Tue, 10 Dec 2019 16:26:11 -0500 |
| Subject: HID: Fix slab-out-of-bounds read in hid_field_extract |
| |
| commit 8ec321e96e056de84022c032ffea253431a83c3c upstream. |
| |
| The syzbot fuzzer found a slab-out-of-bounds bug in the HID report |
| handler. The bug was caused by a report descriptor which included a |
| field with size 12 bits and count 4899, for a total size of 7349 |
| bytes. |
| |
| The usbhid driver uses at most a single-page 4-KB buffer for reports. |
| In the test there wasn't any problem about overflowing the buffer, |
| since only one byte was received from the device. Rather, the bug |
| occurred when the HID core tried to extract the data from the report |
| fields, which caused it to try reading data beyond the end of the |
| allocated buffer. |
| |
| This patch fixes the problem by rejecting any report whose total |
| length exceeds the HID_MAX_BUFFER_SIZE limit (minus one byte to allow |
| for a possible report index). In theory a device could have a report |
| longer than that, but if there was such a thing we wouldn't handle it |
| correctly anyway. |
| |
| Reported-and-tested-by: syzbot+09ef48aa58261464b621@syzkaller.appspotmail.com |
| Signed-off-by: Alan Stern <stern@rowland.harvard.edu> |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/hid/hid-core.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/drivers/hid/hid-core.c |
| +++ b/drivers/hid/hid-core.c |
| @@ -248,6 +248,12 @@ static int hid_add_field(struct hid_pars |
| offset = report->size; |
| report->size += parser->global.report_size * parser->global.report_count; |
| |
| + /* Total size check: Allow for possible report index byte */ |
| + if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) { |
| + hid_err(parser->device, "report is too long\n"); |
| + return -1; |
| + } |
| + |
| if (!parser->local.usage_index) /* Ignore padding fields */ |
| return 0; |
| |