| From 248e5c83fd23e41c2aa9f075f27e769c9763f71a Mon Sep 17 00:00:00 2001 |
| From: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| Date: Sat, 7 Dec 2019 13:05:18 -0800 |
| Subject: [PATCH] HID: hid-input: clear unmapped usages |
| |
| commit 4f3882177240a1f55e45a3d241d3121341bead78 upstream. |
| |
| We should not be leaving half-mapped usages with potentially invalid |
| keycodes, as that may confuse hidinput_find_key() when the key is located |
| by index, which may end up feeding way too large keycode into the VT |
| keyboard handler and cause OOB write there: |
| |
| BUG: KASAN: global-out-of-bounds in clear_bit include/asm-generic/bitops-instrumented.h:56 [inline] |
| BUG: KASAN: global-out-of-bounds in kbd_keycode drivers/tty/vt/keyboard.c:1411 [inline] |
| BUG: KASAN: global-out-of-bounds in kbd_event+0xe6b/0x3790 drivers/tty/vt/keyboard.c:1495 |
| Write of size 8 at addr ffffffff89a1b2d8 by task syz-executor108/1722 |
| ... |
| kbd_keycode drivers/tty/vt/keyboard.c:1411 [inline] |
| kbd_event+0xe6b/0x3790 drivers/tty/vt/keyboard.c:1495 |
| input_to_handler+0x3b6/0x4c0 drivers/input/input.c:118 |
| input_pass_values.part.0+0x2e3/0x720 drivers/input/input.c:145 |
| input_pass_values drivers/input/input.c:949 [inline] |
| input_set_keycode+0x290/0x320 drivers/input/input.c:954 |
| evdev_handle_set_keycode_v2+0xc4/0x120 drivers/input/evdev.c:882 |
| evdev_do_ioctl drivers/input/evdev.c:1150 [inline] |
| |
| Cc: stable@vger.kernel.org |
| Reported-by: syzbot+19340dff067c2d3835c0@syzkaller.appspotmail.com |
| Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| Tested-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c |
| index 63855f275a38..dea9cc65bf80 100644 |
| --- a/drivers/hid/hid-input.c |
| +++ b/drivers/hid/hid-input.c |
| @@ -1132,9 +1132,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel |
| } |
| |
| mapped: |
| - if (device->driver->input_mapped && device->driver->input_mapped(device, |
| - hidinput, field, usage, &bit, &max) < 0) |
| - goto ignore; |
| + if (device->driver->input_mapped && |
| + device->driver->input_mapped(device, hidinput, field, usage, |
| + &bit, &max) < 0) { |
| + /* |
| + * The driver indicated that no further generic handling |
| + * of the usage is desired. |
| + */ |
| + return; |
| + } |
| |
| set_bit(usage->type, input->evbit); |
| |
| @@ -1215,9 +1221,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel |
| set_bit(MSC_SCAN, input->mscbit); |
| } |
| |
| -ignore: |
| return; |
| |
| +ignore: |
| + usage->type = 0; |
| + usage->code = 0; |
| } |
| |
| static void hidinput_handle_scroll(struct hid_usage *usage, |
| -- |
| 2.7.4 |
| |