diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-01-14 16:54:55 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-01-14 18:34:24 -0500 |
| commit | d77651a227f8920dd7ec179b84e400cce844eeb3 (patch) | |
| tree | 64216b5699248263656b7d53b35174efef742876 | |
| parent | 3eb66e91a25497065c5322b1268cbc3953642227 (diff) | |
Input: uinput - fix undefined behavior in uinput_validate_absinfo()
An integer overflow may arise in uinput_validate_absinfo() if "max - min"
can't be represented by an "int". We should check for overflow before
trying to use the result.
Reported-by: Kyungtae Kim <kt0755@gmail.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
| -rw-r--r-- | drivers/input/misc/uinput.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 8ec483e8688b..26ec603fe220 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
| 40 | #include <linux/fs.h> | 40 | #include <linux/fs.h> |
| 41 | #include <linux/miscdevice.h> | 41 | #include <linux/miscdevice.h> |
| 42 | #include <linux/overflow.h> | ||
| 42 | #include <linux/input/mt.h> | 43 | #include <linux/input/mt.h> |
| 43 | #include "../input-compat.h" | 44 | #include "../input-compat.h" |
| 44 | 45 | ||
| @@ -405,7 +406,7 @@ static int uinput_open(struct inode *inode, struct file *file) | |||
| 405 | static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code, | 406 | static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code, |
| 406 | const struct input_absinfo *abs) | 407 | const struct input_absinfo *abs) |
| 407 | { | 408 | { |
| 408 | int min, max; | 409 | int min, max, range; |
| 409 | 410 | ||
| 410 | min = abs->minimum; | 411 | min = abs->minimum; |
| 411 | max = abs->maximum; | 412 | max = abs->maximum; |
| @@ -417,7 +418,7 @@ static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code, | |||
| 417 | return -EINVAL; | 418 | return -EINVAL; |
| 418 | } | 419 | } |
| 419 | 420 | ||
| 420 | if (abs->flat > max - min) { | 421 | if (!check_sub_overflow(max, min, &range) && abs->flat > range) { |
| 421 | printk(KERN_DEBUG | 422 | printk(KERN_DEBUG |
| 422 | "%s: abs_flat #%02x out of range: %d (min:%d/max:%d)\n", | 423 | "%s: abs_flat #%02x out of range: %d (min:%d/max:%d)\n", |
| 423 | UINPUT_NAME, code, abs->flat, min, max); | 424 | UINPUT_NAME, code, abs->flat, min, max); |
