summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2017-01-31 14:56:43 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-14 15:25:34 -0800
commit2089e4563d50c44f187df1ed63a906e05708cf51 (patch)
tree707648a503ff0a4363b4312aabd97f434fc8bd30 /drivers
parent1a815c52d57ebf35bfb516eafada98eeda292d66 (diff)
Input: uinput - fix crash when mixing old and new init style
commit 601bbbe0517303c9f8eb3d75e11d64efed1293c9 upstream. If user tries to initialize uinput device mixing old and new style initialization (i.e. using old UI_SET_ABSBIT instead of UI_ABS_SETUP, we forget to allocate input->absinfo and will crash when trying to send absolute events: ioctl(ui, UI_DEV_SETUP, &us); ioctl(ui, UI_SET_PHYS, "Test"); ioctl(ui, UI_SET_EVBIT, EV_ABS); ioctl(ui, UI_SET_ABSBIT, ABS_X); ioctl(ui, UI_SET_ABSBIT, ABS_Y); ioctl(ui, UI_DEV_CREATE, 0); Reported-by: Rodrigo Rivas Costa <rodrigorivascosta@gmail.com> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=191811 Fixes: fbae10db0940 ("Input: uinput - rework ABS validation") Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/misc/uinput.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 92595b98e7ed..022be0e22eba 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -263,13 +263,21 @@ static int uinput_create_device(struct uinput_device *udev)
return -EINVAL;
}
- if (test_bit(ABS_MT_SLOT, dev->absbit)) {
- nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
- error = input_mt_init_slots(dev, nslot, 0);
- if (error)
+ if (test_bit(EV_ABS, dev->evbit)) {
+ input_alloc_absinfo(dev);
+ if (!dev->absinfo) {
+ error = -EINVAL;
goto fail1;
- } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
- input_set_events_per_packet(dev, 60);
+ }
+
+ if (test_bit(ABS_MT_SLOT, dev->absbit)) {
+ nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
+ error = input_mt_init_slots(dev, nslot, 0);
+ if (error)
+ goto fail1;
+ } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
+ input_set_events_per_packet(dev, 60);
+ }
}
if (test_bit(EV_FF, dev->evbit) && !udev->ff_effects_max) {