From 4fa151b8b81cba6b73e9d90f90da4ced12945136 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 1 Jun 2026 10:07:55 +1000 Subject: [PATCH] totem: require both touch size axes to have resolution We use the resolution later as divisor so let's protect agianst division by zero. This is not an issue on the real device but a malicious uinput device may try to trigger this. Assisted-by: Claude:claude-opus-4-6 (cherry picked from commit 6efbf9ff74ab401009761e86b0ce23caf957266c) Part-of: --- src/evdev-totem.c | 2 +- test/litest.h | 2 ++ test/test-totem.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/evdev-totem.c b/src/evdev-totem.c index 7f262f21..bf9cbebc 100644 --- a/src/evdev-totem.c +++ b/src/evdev-totem.c @@ -753,7 +753,7 @@ totem_reject_device(struct evdev_device *device) libevdev_get_abs_maximum(evdev, ABS_MT_TOOL_TYPE) >= MT_TOOL_DIAL; has_size = evdev_device_get_size(device, &w, &h) == 0; has_touch_size = - libevdev_get_abs_resolution(device->evdev, ABS_MT_TOUCH_MAJOR) > 0 || + libevdev_get_abs_resolution(device->evdev, ABS_MT_TOUCH_MAJOR) > 0 && libevdev_get_abs_resolution(device->evdev, ABS_MT_TOUCH_MINOR) > 0; if (has_xy && has_slot && has_tool_dial && has_size && has_touch_size) diff --git a/test/litest.h b/test/litest.h index b8b8d798..932fb2e0 100644 --- a/test/litest.h +++ b/test/litest.h @@ -40,6 +40,8 @@ #include "litest-runner.h" #include "quirks.h" +DEFINE_DESTROY_CLEANUP_FUNC(libevdev_uinput); + #define START_TEST(func_) \ static enum litest_runner_result func_(const struct litest_runner_test_env *test_env) { \ int _i _unused_ = test_env->rangeval; diff --git a/test/test-totem.c b/test/test-totem.c index 565fbe15..d33a1eed 100644 --- a/test/test-totem.c +++ b/test/test-totem.c @@ -556,6 +556,57 @@ START_TEST(totem_arbitration_outside_rect) } END_TEST +START_TEST(totem_touch_size_missing_resolution) +{ + struct libinput_device *device; + /* Match the Dell Canvas Totem quirk: vendor=0x2575, product=0x0204, + * name matching "*System Multi Axis", bus=USB */ + struct input_id id = { + .bustype = 0x3, + .vendor = 0x2575, + .product = 0x0204, + }; + struct input_absinfo absinfo[] = { + { ABS_MT_SLOT, 0, 4, 0, 0, 0 }, + { ABS_MT_TOUCH_MAJOR, 0, 32767, 0, 0, 10 }, + { ABS_MT_TOUCH_MINOR, 0, 32767, 0, 0, 0 }, /* resolution missing */ + { ABS_MT_ORIENTATION, -89, 89, 0, 0, 0 }, + { ABS_MT_POSITION_X, 0, 32767, 0, 0, 55 }, + { ABS_MT_POSITION_Y, 0, 32767, 0, 0, 98 }, + { ABS_MT_TOOL_TYPE, 9, 10, 0, 0, 0 }, + { ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 }, + { -1, -1, -1, -1, -1, -1 }, + }; + /* clang-format off */ + int events[] = { + EV_KEY, BTN_0, + INPUT_PROP_MAX, INPUT_PROP_DIRECT, + -1, -1, + }; + /* clang-format on */ + + _destroy_(libevdev_uinput) *uinput = + litest_create_uinput_device_from_description( + "CoolTouch System Multi Axis", + &id, + absinfo, + events); + _litest_context_destroy_ struct libinput *li = litest_create_context(); + litest_disable_log_handler(li); + device = libinput_path_add_device(li, libevdev_uinput_get_devnode(uinput)); + litest_restore_log_handler(li); + + /* The device matches the Dell Canvas Totem quirk but has + * ABS_MT_TOUCH_MINOR resolution missing. The totem dispatch + * should reject it, so it must not be recognized as a tablet + * tool device. */ + if (device) + litest_assert(!libinput_device_has_capability( + device, + LIBINPUT_DEVICE_CAP_TABLET_TOOL)); +} +END_TEST + TEST_COLLECTION(totem) { /* clang-format off */ @@ -571,6 +622,7 @@ TEST_COLLECTION(totem) litest_add(totem_button, LITEST_TOTEM, LITEST_ANY); litest_add(totem_button_down_on_init, LITEST_TOTEM, LITEST_ANY); litest_add_no_device(totem_button_up_on_delete); + litest_add_no_device(totem_touch_size_missing_resolution); litest_add(totem_arbitration_below, LITEST_TOTEM, LITEST_ANY); litest_add(totem_arbitration_during, LITEST_TOTEM, LITEST_ANY);