| From 601bbbe0517303c9f8eb3d75e11d64efed1293c9 Mon Sep 17 00:00:00 2001 |
| From: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| Date: Tue, 31 Jan 2017 14:56:43 -0800 |
| Subject: Input: uinput - fix crash when mixing old and new init style |
| |
| From: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| |
| 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> |
| |
| --- |
| drivers/input/misc/uinput.c | 20 ++++++++++++++------ |
| 1 file changed, 14 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/input/misc/uinput.c |
| +++ b/drivers/input/misc/uinput.c |
| @@ -263,13 +263,21 @@ static int uinput_create_device(struct u |
| 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) { |