Skip to content

Commit 2080845

Browse files
dtorSomasundaram Krishnasamy
authored andcommitted
Input: add safety guards to input_set_keycode()
commit cb222ae 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: [email protected] Reported-by: [email protected] Link: https://lore.kernel.org/r/20191207212757.GA245964@dtor-ws Signed-off-by: Dmitry Torokhov <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit af62c38) Orabug: 31200557 CVE: CVE-2019-20636 Signed-off-by: Vijayendra Suman <[email protected]> Reviewed-by: Allen Pais <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent 7c2d10a commit 2080845

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
@@ -858,16 +858,18 @@ static int input_default_setkeycode(struct input_dev *dev,
858858
}
859859
}
860860

861-
__clear_bit(*old_keycode, dev->keybit);
862-
__set_bit(ke->keycode, dev->keybit);
863-
864-
for (i = 0; i < dev->keycodemax; i++) {
865-
if (input_fetch_keycode(dev, i) == *old_keycode) {
866-
__set_bit(*old_keycode, dev->keybit);
867-
break; /* Setting the bit twice is useless, so break */
861+
if (*old_keycode <= KEY_MAX) {
862+
__clear_bit(*old_keycode, dev->keybit);
863+
for (i = 0; i < dev->keycodemax; i++) {
864+
if (input_fetch_keycode(dev, i) == *old_keycode) {
865+
__set_bit(*old_keycode, dev->keybit);
866+
/* Setting the bit twice is useless, so break */
867+
break;
868+
}
868869
}
869870
}
870871

872+
__set_bit(ke->keycode, dev->keybit);
871873
return 0;
872874
}
873875

@@ -923,9 +925,13 @@ int input_set_keycode(struct input_dev *dev,
923925
* Simulate keyup event if keycode is not present
924926
* in the keymap anymore
925927
*/
926-
if (test_bit(EV_KEY, dev->evbit) &&
927-
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
928-
__test_and_clear_bit(old_keycode, dev->key)) {
928+
if (old_keycode > KEY_MAX) {
929+
dev_warn(dev->dev.parent ?: &dev->dev,
930+
"%s: got too big old keycode %#x\n",
931+
__func__, old_keycode);
932+
} else if (test_bit(EV_KEY, dev->evbit) &&
933+
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
934+
__test_and_clear_bit(old_keycode, dev->key)) {
929935
struct input_value vals[] = {
930936
{ EV_KEY, old_keycode, 0 },
931937
input_value_sync

0 commit comments

Comments
 (0)