[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1587683028.915720247@decadent.org.uk>
Date: Fri, 24 Apr 2020 00:07:21 +0100
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org, Denis Kirjanov <kda@...ux-powerpc.org>,
syzbot+c769968809f9359b07aa@...kaller.appspotmail.com,
syzbot+76f3a30e88d256644c78@...kaller.appspotmail.com,
"Dmitry Torokhov" <dmitry.torokhov@...il.com>
Subject: [PATCH 3.16 214/245] Input: add safety guards to input_set_keycode()
3.16.83-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <dmitry.torokhov@...il.com>
commit cb222aed03d798fc074be55e59d9a112338ee784 upstream.
If we happen to have a garbage in input device's keycode table with values
too big we'll end up doing clear_bit() with offset way outside of our
bitmaps, damaging other objects within an input device or even outside of
it. Let's add sanity checks to the returned old keycodes.
Reported-by: syzbot+c769968809f9359b07aa@...kaller.appspotmail.com
Reported-by: syzbot+76f3a30e88d256644c78@...kaller.appspotmail.com
Link: https://lore.kernel.org/r/20191207212757.GA245964@dtor-ws
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@...il.com>
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
drivers/input/input.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -841,16 +841,18 @@ static int input_default_setkeycode(stru
}
}
- __clear_bit(*old_keycode, dev->keybit);
- __set_bit(ke->keycode, dev->keybit);
-
- for (i = 0; i < dev->keycodemax; i++) {
- if (input_fetch_keycode(dev, i) == *old_keycode) {
- __set_bit(*old_keycode, dev->keybit);
- break; /* Setting the bit twice is useless, so break */
+ if (*old_keycode <= KEY_MAX) {
+ __clear_bit(*old_keycode, dev->keybit);
+ for (i = 0; i < dev->keycodemax; i++) {
+ if (input_fetch_keycode(dev, i) == *old_keycode) {
+ __set_bit(*old_keycode, dev->keybit);
+ /* Setting the bit twice is useless, so break */
+ break;
+ }
}
}
+ __set_bit(ke->keycode, dev->keybit);
return 0;
}
@@ -906,9 +908,13 @@ int input_set_keycode(struct input_dev *
* Simulate keyup event if keycode is not present
* in the keymap anymore
*/
- if (test_bit(EV_KEY, dev->evbit) &&
- !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
- __test_and_clear_bit(old_keycode, dev->key)) {
+ if (old_keycode > KEY_MAX) {
+ dev_warn(dev->dev.parent ?: &dev->dev,
+ "%s: got too big old keycode %#x\n",
+ __func__, old_keycode);
+ } else if (test_bit(EV_KEY, dev->evbit) &&
+ !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
+ __test_and_clear_bit(old_keycode, dev->key)) {
struct input_value vals[] = {
{ EV_KEY, old_keycode, 0 },
input_value_sync
Powered by blists - more mailing lists