Input: add safety guards to input_set_keycode()
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / input / input.c
index 50d425fe6706faf84596851a730a0e62b860d1cb..cadb368be8eff68fea2e4396ef3e8217c73efc1e 100644 (file)
@@ -858,16 +858,18 @@ static int input_default_setkeycode(struct input_dev *dev,
                }
        }
 
-       __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;
 }
 
@@ -923,9 +925,13 @@ 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) &&
-           !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