Skip to content

Commit cb222ae

Browse files
committed
Input: add safety guards to input_set_keycode()
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: [email protected] Reported-by: [email protected] Link: https://lore.kernel.org/r/20191207212757.GA245964@dtor-ws Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent f729a1b commit cb222ae

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

drivers/input/input.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -878,16 +878,18 @@ static int input_default_setkeycode(struct input_dev *dev,
878878
}
879879
}
880880

881-
__clear_bit(*old_keycode, dev->keybit);
882-
__set_bit(ke->keycode, dev->keybit);
883-
884-
for (i = 0; i < dev->keycodemax; i++) {
885-
if (input_fetch_keycode(dev, i) == *old_keycode) {
886-
__set_bit(*old_keycode, dev->keybit);
887-
break; /* Setting the bit twice is useless, so break */
881+
if (*old_keycode <= KEY_MAX) {
882+
__clear_bit(*old_keycode, dev->keybit);
883+
for (i = 0; i < dev->keycodemax; i++) {
884+
if (input_fetch_keycode(dev, i) == *old_keycode) {
885+
__set_bit(*old_keycode, dev->keybit);
886+
/* Setting the bit twice is useless, so break */
887+
break;
888+
}
888889
}
889890
}
890891

892+
__set_bit(ke->keycode, dev->keybit);
891893
return 0;
892894
}
893895

@@ -943,9 +945,13 @@ int input_set_keycode(struct input_dev *dev,
943945
* Simulate keyup event if keycode is not present
944946
* in the keymap anymore
945947
*/
946-
if (test_bit(EV_KEY, dev->evbit) &&
947-
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
948-
__test_and_clear_bit(old_keycode, dev->key)) {
948+
if (old_keycode > KEY_MAX) {
949+
dev_warn(dev->dev.parent ?: &dev->dev,
950+
"%s: got too big old keycode %#x\n",
951+
__func__, old_keycode);
952+
} else if (test_bit(EV_KEY, dev->evbit) &&
953+
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
954+
__test_and_clear_bit(old_keycode, dev->key)) {
949955
struct input_value vals[] = {
950956
{ EV_KEY, old_keycode, 0 },
951957
input_value_sync

0 commit comments

Comments
 (0)