diff -Nru libinput-1.10.4/debian/changelog libinput-1.10.4/debian/changelog --- libinput-1.10.4/debian/changelog 2018-04-09 10:16:50.000000000 +0000 +++ libinput-1.10.4/debian/changelog 2022-04-19 07:08:40.000000000 +0000 @@ -1,3 +1,28 @@ +libinput (1.10.4-1ubuntu0.18.04.3) bionic-security; urgency=medium + + * SECURITY UPDATE: Format string vulnerability + - d/p/0001-evdev-strip-the-device-name-of-format-directives.patch: + Cleanup device name to ensure format string directives are + neutralised when logging in src/evdev.c. Based on upstream patch. + - CVE-2022-1215 + + -- Alex Murray Tue, 19 Apr 2022 16:38:40 +0930 + +libinput (1.10.4-1ubuntu0.18.04.2) bionic; urgency=medium + + * Unset INPUT_PROP_BUTTONPAD for Dell Precision 7x50. (LP: #1905819) + * Update control build-dep libevdev-dev (>= 1.5.8+dfsg-1ubuntu0.1) for + libevdev_disable_property API. + + -- Kai-Chuan Hsieh Mon, 30 Nov 2020 20:08:24 +0800 + +libinput (1.10.4-1ubuntu0.18.04.1) bionic; urgency=medium + + * dont-disable-tapping-on-mt-tool-palm.diff: Don't disable tapping if + tool-based palm is detected. (LP: #1837962) + + -- Timo Aaltonen Mon, 29 Jul 2019 09:12:33 +0300 + libinput (1.10.4-1) unstable; urgency=medium * New upstream release. diff -Nru libinput-1.10.4/debian/control libinput-1.10.4/debian/control --- libinput-1.10.4/debian/control 2018-04-09 08:50:44.000000000 +0000 +++ libinput-1.10.4/debian/control 2022-04-19 07:08:40.000000000 +0000 @@ -1,7 +1,8 @@ Source: libinput Section: libs Priority: optional -Maintainer: Debian X Strike Force +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian X Strike Force Uploaders: Emilio Pozuelo Monfort , Héctor Orón Martínez Build-Depends: debhelper (>= 10), @@ -9,7 +10,7 @@ pkg-config, libmtdev-dev (>= 1.1.0), libudev-dev, - libevdev-dev (>= 0.4), + libevdev-dev (>= 1.5.8+dfsg-1ubuntu0.1), libwacom-dev (>= 0.20), Standards-Version: 4.1.1 Vcs-Git: https://salsa.debian.org/xorg-team/lib/libinput.git @@ -71,7 +72,7 @@ libinput10 (= ${binary:Version}), libmtdev-dev (>= 1.1.0), libudev-dev, - libevdev-dev (>= 0.4), + libevdev-dev (>= 1.5.8+dfsg-1ubuntu0.1), libwacom-dev (>= 0.20), ${shlibs:Depends}, ${misc:Depends}, diff -Nru libinput-1.10.4/debian/patches/0001-evdev-strip-the-device-name-of-format-directives.patch libinput-1.10.4/debian/patches/0001-evdev-strip-the-device-name-of-format-directives.patch --- libinput-1.10.4/debian/patches/0001-evdev-strip-the-device-name-of-format-directives.patch 1970-01-01 00:00:00.000000000 +0000 +++ libinput-1.10.4/debian/patches/0001-evdev-strip-the-device-name-of-format-directives.patch 2022-04-19 07:08:40.000000000 +0000 @@ -0,0 +1,267 @@ +Backport of the following upstream patch: + +From 6d11367f31e37c4bb3902e91ffebd5418a957f67 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Wed, 30 Mar 2022 09:25:22 +1000 +Subject: [PATCH] evdev: strip the device name of format directives +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes a format string vulnerabilty. + +evdev_log_message() composes a format string consisting of a fixed +prefix (including the rendered device name) and the passed-in format +buffer. This format string is then passed with the arguments to the +actual log handler, which usually and eventually ends up being printf. + +If the device name contains a printf-style format directive, these ended +up in the format string and thus get interpreted correctly, e.g. for a +device "Foo%sBar" the log message vs printf invocation ends up being: + evdev_log_message(device, "some message %s", "some argument"); + printf("event9 - Foo%sBar: some message %s", "some argument"); + +This can enable an attacker to execute malicious code with the +privileges of the process using libinput. + +To exploit this, an attacker needs to be able to create a kernel device +with a malicious name, e.g. through /dev/uinput or a Bluetooth device. + +To fix this, convert any potential format directives in the device name +by duplicating percentages. + +Pre-rendering the device to avoid the issue altogether would be nicer +but the current log level hooks do not easily allow for this. The device +name is the only user-controlled part of the format string. + +A second potential issue is the sysname of the device which is also +sanitized. + +This issue was found by Albin Eldstål-Ahrens and Benjamin Svensson from +Assured AB. + +Signed-off-by: Peter Hutterer +--- + meson.build | 1 + + src/evdev.c | 31 +++++++++++------ + src/evdev.h | 6 ++-- + src/util-strings.h | 30 ++++++++++++++++ + test/litest-device-format-string.c | 56 ++++++++++++++++++++++++++++++ + test/litest.h | 1 + + test/test-utils.c | 26 ++++++++++++++ + 7 files changed, 139 insertions(+), 12 deletions(-) + create mode 100644 test/litest-device-format-string.c + +--- a/meson.build ++++ b/meson.build +@@ -543,6 +543,7 @@ + 'test/litest-device-calibrated-touchscreen.c', + 'test/litest-device-cyborg-rat-5.c', + 'test/litest-device-elantech-touchpad.c', ++ 'test/litest-device-format-string.c', + 'test/litest-device-generic-singletouch.c', + 'test/litest-device-gpio-keys.c', + 'test/litest-device-huion-pentablet.c', +--- a/src/evdev.c ++++ b/src/evdev.c +@@ -1913,6 +1913,35 @@ + return value && !streq(value, "0"); + } + ++/** ++ * Return a copy of str with all % converted to %% to make the string ++ * acceptable as printf format. ++ */ ++static inline char * ++str_sanitize(const char *str) ++{ ++ if (!str) ++ return NULL; ++ ++ if (!strchr(str, '%')) ++ return strdup(str); ++ ++ size_t slen = min(strlen(str), 512); ++ char *sanitized = zalloc(2 * slen + 1); ++ const char *src = str; ++ char *dst = sanitized; ++ ++ for (size_t i = 0; i < slen; i++) { ++ if (*src == '%') ++ *dst++ = '%'; ++ *dst++ = *src++; ++ } ++ *dst = '\0'; ++ ++ return sanitized; ++} ++ ++ + struct evdev_device * + evdev_device_create(struct libinput_seat *seat, + struct udev_device *udev_device) +@@ -1920,19 +1949,19 @@ + struct libinput *libinput = seat->libinput; + struct evdev_device *device = NULL; + int rc; +- int fd; ++ int fd = -1; + int unhandled_device = 0; + const char *devnode = udev_device_get_devnode(udev_device); +- const char *sysname = udev_device_get_sysname(udev_device); ++ char *sysname = str_sanitize(udev_device_get_sysname(udev_device)); + + if (!devnode) { + log_info(libinput, "%s: no device node associated\n", sysname); +- return NULL; ++ goto err; + } + + if (udev_device_should_be_ignored(udev_device)) { + log_debug(libinput, "%s: device is ignored\n", sysname); +- return NULL; ++ goto err; + } + + /* Use non-blocking mode so that we can loop on read on +@@ -1946,13 +1975,15 @@ + sysname, + devnode, + strerror(-fd)); +- return NULL; ++ goto err; + } + + if (!evdev_device_have_same_syspath(udev_device, fd)) + goto err; + + device = zalloc(sizeof *device); ++ device->sysname = sysname; ++ sysname = NULL; + + libinput_device_init(&device->base, seat); + libinput_seat_ref(seat); +@@ -1975,6 +2006,9 @@ + device->dispatch = NULL; + device->fd = fd; + device->devname = libevdev_get_name(device->evdev); ++ /* the log_prefix_name is used as part of a printf format string and ++ * must not contain % directives, see evdev_log_msg */ ++ device->log_prefix_name = str_sanitize(device->devname); + device->scroll.threshold = 5.0; /* Default may be overridden */ + device->scroll.direction_lock_threshold = 5.0; /* Default may be overridden */ + device->scroll.direction = 0; +@@ -2022,6 +2056,7 @@ + if (device) + evdev_device_destroy(device); + ++ free(sysname); + return unhandled_device ? EVDEV_UNHANDLED_DEVICE : NULL; + } + +@@ -2034,7 +2069,7 @@ + const char * + evdev_device_get_sysname(struct evdev_device *device) + { +- return udev_device_get_sysname(device->udev_device); ++ return device->sysname; + } + + const char * +@@ -2540,6 +2575,8 @@ + if (device->base.group) + libinput_device_group_unref(device->base.group); + ++ free(device->log_prefix_name); ++ free(device->sysname); + free(device->output_name); + filter_destroy(device->pointer.filter); + libinput_timer_destroy(&device->scroll.timer); +--- a/src/evdev.h ++++ b/src/evdev.h +@@ -179,6 +179,8 @@ + struct udev_device *udev_device; + char *output_name; + const char *devname; ++ char *log_prefix_name; ++ char *sysname; + bool was_removed; + int fd; + enum evdev_device_seat_capability seat_caps; +@@ -705,7 +707,7 @@ + sizeof(buf), + "%-7s - %s%s%s", + evdev_device_get_sysname(device), +- (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? device->devname : "", ++ (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? device->log_prefix_name : "", + (priority > LIBINPUT_LOG_PRIORITY_DEBUG) ? ": " : "", + format); + +--- /dev/null ++++ b/test/litest-device-format-string.c +@@ -0,0 +1,55 @@ ++ ++/* ++ * Copyright © 2013 Red Hat, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include "config.h" ++ ++#include "litest.h" ++#include "litest-int.h" ++ ++static struct input_id input_id = { ++ .bustype = 0x3, ++ .vendor = 0x0123, ++ .product = 0x0456, ++}; ++ ++static int events[] = { ++ EV_KEY, BTN_LEFT, ++ EV_KEY, BTN_RIGHT, ++ EV_KEY, BTN_MIDDLE, ++ EV_REL, REL_X, ++ EV_REL, REL_Y, ++ EV_REL, REL_WHEEL, ++ -1 , -1, ++}; ++ ++TEST_DEVICE("mouse-format-string", ++ .type = LITEST_MOUSE_FORMAT_STRING, ++ .features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL, ++ .interface = NULL, ++ ++ .name = "Evil %s %d %x Mouse %p %", ++ .id = &input_id, ++ .absinfo = NULL, ++ .events = events, ++) +--- a/test/litest.h ++++ b/test/litest.h +@@ -271,6 +271,7 @@ + LITEST_WACOM_BAMBOO_2FG_FINGER, + LITEST_HP_WMI_HOTKEYS, + LITEST_MS_NANO_TRANSCEIVER_MOUSE, ++ LITEST_MOUSE_FORMAT_STRING, + }; + + enum litest_device_feature { diff -Nru libinput-1.10.4/debian/patches/add-device-quirk-for-dell-precision-7x50.patch libinput-1.10.4/debian/patches/add-device-quirk-for-dell-precision-7x50.patch --- libinput-1.10.4/debian/patches/add-device-quirk-for-dell-precision-7x50.patch 1970-01-01 00:00:00.000000000 +0000 +++ libinput-1.10.4/debian/patches/add-device-quirk-for-dell-precision-7x50.patch 2020-11-30 12:08:24.000000000 +0000 @@ -0,0 +1,52 @@ +quirks: add quirk for Dell Precision 7550/7750 touchpad + +Dell Precision 7550/7750 touchpad report device capability denoted by [1] is wrongly +configured as clickpad, so that kernel driver will set INPUT_PROP_BUTTONPAD bit, +unset it for keep handling BTN_RIGHT event in libinput. + +[1] https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections +--- a/udev/90-libinput-model-quirks.hwdb ++++ b/udev/90-libinput-model-quirks.hwdb +@@ -97,6 +97,9 @@ + libinput:name:*AlpsPS/2 ALPS GlidePoint:dmi:*svnDellInc.:pnLatitudeE6220:* + LIBINPUT_ATTR_PRESSURE_RANGE=100:90 + ++libinput:name:DELL09C?:00 0488:120A Touchpad:dmi:*svnDellInc.:pnPrecision7?50:* ++ LIBINPUT_MODEL_DELL_PRECISION7X50_TOUCHPAD=1 ++ + ########################################## + # Elantech + ########################################## +--- a/src/evdev.h ++++ b/src/evdev.h +@@ -125,6 +125,7 @@ + EVDEV_MODEL_LOGITECH_MARBLE_MOUSE = (1 << 26), + EVDEV_MODEL_TABLET_NO_PROXIMITY_OUT = (1 << 27), + EVDEV_MODEL_MS_NANO_TRANSCEIVER = (1 << 28), ++ EVDEV_MODEL_DELL_PRECISION7X50_TOUCHPAD = (1 << 29), + }; + + enum evdev_button_scroll_state { +--- a/src/evdev.c ++++ b/src/evdev.c +@@ -1265,6 +1265,7 @@ + MODEL(LOGITECH_MARBLE_MOUSE), + MODEL(TABLET_NO_PROXIMITY_OUT), + MODEL(MS_NANO_TRANSCEIVER), ++ MODEL(DELL_PRECISION7X50_TOUCHPAD), + #undef MODEL + { "ID_INPUT_TRACKBALL", EVDEV_MODEL_TRACKBALL }, + { NULL, EVDEV_MODEL_DEFAULT }, +@@ -1861,6 +1862,12 @@ + /* Logitech Marble Mouse claims to have a middle button */ + if (device->model_flags & EVDEV_MODEL_LOGITECH_MARBLE_MOUSE) + libevdev_disable_event_code(device->evdev, EV_KEY, BTN_MIDDLE); ++ ++ /* Touchpad is not a clickpad but INPUT_PROP_BUTTONPAD is set */ ++ if (device->model_flags & EVDEV_MODEL_DELL_PRECISION7X50_TOUCHPAD) ++ libevdev_disable_property(device->evdev, ++ INPUT_PROP_BUTTONPAD); ++ + } + + static void diff -Nru libinput-1.10.4/debian/patches/dont-disable-tapping-on-mt-tool-palm.diff libinput-1.10.4/debian/patches/dont-disable-tapping-on-mt-tool-palm.diff --- libinput-1.10.4/debian/patches/dont-disable-tapping-on-mt-tool-palm.diff 1970-01-01 00:00:00.000000000 +0000 +++ libinput-1.10.4/debian/patches/dont-disable-tapping-on-mt-tool-palm.diff 2019-07-29 06:01:55.000000000 +0000 @@ -0,0 +1,88 @@ +commit 237ebb7cc4e9bf035891176acb08b1bf558ee989 +Author: Peter Hutterer +Date: Mon Jun 25 14:50:22 2018 +1000 + + touchpad: don't disable tapping on MT_TOOL_PALM + + The tapping code can handle palm states now, so there is no need to disable + tapping altogether when a tool-based palm is detected. + + Fixes https://gitlab.freedesktop.org/libinput/libinput/issues/65 + + Signed-off-by: Peter Hutterer + +diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c +index 3cac36c2..03ea9b38 100644 +--- a/src/evdev-mt-touchpad.c ++++ b/src/evdev-mt-touchpad.c +@@ -842,9 +842,6 @@ tp_palm_detect_tool_triggered(struct tp_dispatch *tp, + !t->is_tool_palm) + t->palm.state = PALM_NONE; + +- if (t->palm.state == PALM_TOOL_PALM) +- tp_stop_actions(tp, time); +- + return t->palm.state == PALM_TOOL_PALM; + } + +diff --git a/test/test-touchpad.c b/test/test-touchpad.c +index 2294bb88..b4b28f08 100644 +--- a/test/test-touchpad.c ++++ b/test/test-touchpad.c +@@ -1541,6 +1541,48 @@ START_TEST(touchpad_palm_detect_tool_palm_on_off) + } + END_TEST + ++START_TEST(touchpad_palm_detect_tool_palm_tap_after) ++{ ++ struct litest_device *dev = litest_current_device(); ++ struct libinput *li = dev->libinput; ++ ++ if (!touchpad_has_tool_palm(dev)) ++ return; ++ ++ litest_enable_tap(dev->libinput_device); ++ litest_drain_events(li); ++ ++ litest_push_event_frame(dev); ++ litest_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM); ++ litest_touch_down(dev, 0, 50, 50); ++ litest_pop_event_frame(dev); ++ libinput_dispatch(li); ++ ++ litest_touch_move_to(dev, 0, 50, 50, 50, 80, 10, 0); ++ libinput_dispatch(li); ++ ++ litest_assert_empty_queue(li); ++ ++ litest_push_event_frame(dev); ++ litest_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER); ++ litest_touch_up(dev, 0); ++ litest_pop_event_frame(dev); ++ libinput_dispatch(li); ++ litest_timeout_tap(); ++ litest_assert_empty_queue(li); ++ ++ litest_touch_down(dev, 0, 50, 50); ++ libinput_dispatch(li); ++ litest_touch_up(dev, 0); ++ libinput_dispatch(li); ++ litest_timeout_tap(); ++ ++ litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED); ++ litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED); ++ litest_assert_empty_queue(li); ++} ++END_TEST ++ + START_TEST(touchpad_palm_detect_tool_palm_tap) + { + struct litest_device *dev = litest_current_device(); +@@ -6336,6 +6378,7 @@ TEST_COLLECTION(touchpad) + litest_add("touchpad:palm", touchpad_palm_detect_tool_palm, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:palm", touchpad_palm_detect_tool_palm_on_off, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:palm", touchpad_palm_detect_tool_palm_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); ++ litest_add("touchpad:palm", touchpad_palm_detect_tool_palm_tap_after, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:palm", touchpad_palm_detect_touch_size, LITEST_APPLE_CLICKPAD, LITEST_ANY); + + litest_add("touchpad:palm", touchpad_palm_detect_pressure, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); diff -Nru libinput-1.10.4/debian/patches/series libinput-1.10.4/debian/patches/series --- libinput-1.10.4/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ libinput-1.10.4/debian/patches/series 2022-04-19 06:59:47.000000000 +0000 @@ -0,0 +1,3 @@ +dont-disable-tapping-on-mt-tool-palm.diff +add-device-quirk-for-dell-precision-7x50.patch +0001-evdev-strip-the-device-name-of-format-directives.patch