Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5b9bfbe authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Greg Kroah-Hartman
Browse files

Input: add safety guards to input_set_keycode()



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: default avatar <syzbot+c769968809f9359b07aa@syzkaller.appspotmail.com>
Reported-by: default avatar <syzbot+76f3a30e88d256644c78@syzkaller.appspotmail.com>
Link: https://lore.kernel.org/r/20191207212757.GA245964@dtor-ws


Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 64c8b76e
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -858,16 +858,18 @@ static int input_default_setkeycode(struct input_dev *dev,
		}
	}

	if (*old_keycode <= KEY_MAX) {
		__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 */
				/* Setting the bit twice is useless, so break */
				break;
			}
		}
	}

	__set_bit(ke->keycode, dev->keybit);
	return 0;
}

@@ -923,7 +925,11 @@ int input_set_keycode(struct input_dev *dev,
	 * Simulate keyup event if keycode is not present
	 * in the keymap anymore
	 */
	if (test_bit(EV_KEY, dev->evbit) &&
	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[] =  {