Version in base suite: 1.28.1-1 Base version: libinput_1.28.1-1 Target version: libinput_1.28.1-1+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libi/libinput/libinput_1.28.1-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libi/libinput/libinput_1.28.1-1+deb13u1.dsc changelog | 9 patches/libinput-device-group-sanitize-phys-before-printing-.patch | 89 ++++++++ patches/series | 3 patches/util-don-t-call-function-in-macro-argument.patch | 27 ++ patches/util-sanitize-control-characters-in-str_sanitize.patch | 100 ++++++++++ 5 files changed, 228 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmps2bu2kj7/libinput_1.28.1-1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmps2bu2kj7/libinput_1.28.1-1+deb13u1.dsc: no acceptable signature found diff -Nru libinput-1.28.1/debian/changelog libinput-1.28.1/debian/changelog --- libinput-1.28.1/debian/changelog 2025-04-03 12:47:30.000000000 +0000 +++ libinput-1.28.1/debian/changelog 2026-06-08 20:16:56.000000000 +0000 @@ -1,3 +1,12 @@ +libinput (1.28.1-1+deb13u1) trixie-security; urgency=high + + * Non-maintainer upload by the Security Team. + * util: don't call function in macro argument + * util: sanitize control characters in str_sanitize() + * libinput-device-group: sanitize phys before printing it (CVE-2026-50292) + + -- Salvatore Bonaccorso Mon, 08 Jun 2026 22:16:56 +0200 + libinput (1.28.1-1) unstable; urgency=medium * New upstream release. diff -Nru libinput-1.28.1/debian/patches/libinput-device-group-sanitize-phys-before-printing-.patch libinput-1.28.1/debian/patches/libinput-device-group-sanitize-phys-before-printing-.patch --- libinput-1.28.1/debian/patches/libinput-device-group-sanitize-phys-before-printing-.patch 1970-01-01 00:00:00.000000000 +0000 +++ libinput-1.28.1/debian/patches/libinput-device-group-sanitize-phys-before-printing-.patch 2026-06-08 20:14:17.000000000 +0000 @@ -0,0 +1,89 @@ +From: Peter Hutterer +Date: Mon, 1 Jun 2026 10:48:24 +1000 +Subject: libinput-device-group: sanitize phys before printing it +Origin: https://gitlab.freedesktop.org/libinput/libinput/-/commit/b2bde9504d42a5976d76e1f27c640dc561fbd99b +Bug: https://gitlab.freedesktop.org/libinput/libinput/-/work_items/1296 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-50292 + +A malicious uinput device could set the phys value (via UI_SET_PHYS) +to contain a '\n'. When the value is printed as part of the device group +the udev rules will interpret it as separate property. + +Depending on the property this can cause local privilege escalation. + +Closes #1296 + +Found-by: Csome +(cherry picked from commit 76f0d8a7f57e2868882864b4611281f12f704b55) + +Part-of: +--- + udev/libinput-device-group.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/udev/libinput-device-group.c ++++ b/udev/libinput-device-group.c +@@ -109,7 +109,8 @@ wacom_handle_ekr(struct udev_device *dev + + udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) { + struct udev_device *d; +- const char *path, *phys; ++ char *phys = NULL; ++ const char *path; + const char *pidstr, *vidstr; + int pid, vid, dist; + +@@ -124,7 +125,7 @@ wacom_handle_ekr(struct udev_device *dev + + vidstr = udev_device_get_property_value(d, "ID_VENDOR_ID"); + pidstr = udev_device_get_property_value(d, "ID_MODEL_ID"); +- phys = udev_device_get_sysattr_value(d, "phys"); ++ phys = str_sanitize(udev_device_get_sysattr_value(d, "phys")); + + if (vidstr && pidstr && phys && + safe_atoi_base(vidstr, &vid, 16) && +@@ -138,11 +139,13 @@ wacom_handle_ekr(struct udev_device *dev + best_dist = dist; + + free(*phys_attr); +- *phys_attr = safe_strdup(phys); ++ *phys_attr = phys; ++ phys = NULL; + } + } + + udev_device_unref(d); ++ free(phys); + } + + udev_enumerate_unref(e); +@@ -154,8 +157,8 @@ int main(int argc, char **argv) + int rc = 1; + struct udev *udev = NULL; + struct udev_device *device = NULL; +- const char *syspath, +- *phys = NULL; ++ char *phys = NULL; ++ const char *syspath = NULL; + const char *product; + int bustype, vendor_id, product_id, version; + char group[1024]; +@@ -179,8 +182,7 @@ int main(int argc, char **argv) + * bit and use the remainder as device group identifier */ + while (device != NULL) { + struct udev_device *parent; +- +- phys = udev_device_get_sysattr_value(device, "phys"); ++ phys = str_sanitize(udev_device_get_sysattr_value(device, "phys")); + if (phys) + break; + +@@ -249,6 +251,8 @@ int main(int argc, char **argv) + + printf("LIBINPUT_DEVICE_GROUP=%s\n", group); + ++ free(phys); ++ + rc = 0; + out: + if (device) diff -Nru libinput-1.28.1/debian/patches/series libinput-1.28.1/debian/patches/series --- libinput-1.28.1/debian/patches/series 2025-04-03 12:44:47.000000000 +0000 +++ libinput-1.28.1/debian/patches/series 2026-06-08 20:14:17.000000000 +0000 @@ -1,2 +1,5 @@ #placeholder tools-remove-references-to-libinput_quir.patch +util-don-t-call-function-in-macro-argument.patch +util-sanitize-control-characters-in-str_sanitize.patch +libinput-device-group-sanitize-phys-before-printing-.patch diff -Nru libinput-1.28.1/debian/patches/util-don-t-call-function-in-macro-argument.patch libinput-1.28.1/debian/patches/util-don-t-call-function-in-macro-argument.patch --- libinput-1.28.1/debian/patches/util-don-t-call-function-in-macro-argument.patch 1970-01-01 00:00:00.000000000 +0000 +++ libinput-1.28.1/debian/patches/util-don-t-call-function-in-macro-argument.patch 2026-06-08 20:13:17.000000000 +0000 @@ -0,0 +1,27 @@ +From: =?UTF-8?q?Kacper=20Piwi=C5=84ski?= +Date: Sun, 29 Jun 2025 07:21:27 +0000 +Subject: util: don't call function in macro argument +Origin: https://gitlab.freedesktop.org/libinput/libinput/-/commit/8c15a01d1692cf0301b25ec2ead1d15d8176ad29 + +Part-of: +--- + src/util-strings.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/util-strings.h b/src/util-strings.h +index 870995f59e85..fc37ac4bb95c 100644 +--- a/src/util-strings.h ++++ b/src/util-strings.h +@@ -547,7 +547,8 @@ str_sanitize(const char *str) + if (!strchr(str, '%')) + return strdup(str); + +- size_t slen = min(strlen(str), 512); ++ size_t slen = strlen(str); ++ slen = min(slen, 512); + char *sanitized = zalloc(2 * slen + 1); + const char *src = str; + char *dst = sanitized; +-- +2.53.0 + diff -Nru libinput-1.28.1/debian/patches/util-sanitize-control-characters-in-str_sanitize.patch libinput-1.28.1/debian/patches/util-sanitize-control-characters-in-str_sanitize.patch --- libinput-1.28.1/debian/patches/util-sanitize-control-characters-in-str_sanitize.patch 1970-01-01 00:00:00.000000000 +0000 +++ libinput-1.28.1/debian/patches/util-sanitize-control-characters-in-str_sanitize.patch 2026-06-08 20:14:17.000000000 +0000 @@ -0,0 +1,100 @@ +From: Peter Hutterer +Date: Mon, 1 Jun 2026 10:12:29 +1000 +Subject: util: sanitize control characters in str_sanitize() +Origin: https://gitlab.freedesktop.org/libinput/libinput/-/commit/fc2262e1c1847021239065e84f39f15492ef05cc + +str_sanitize() only escaped '%' characters for format string safety. +Device names from uinput devices can contain arbitrary bytes including +ANSI escape sequences (ESC, 0x1b) and other control characters. When +these strings are included in log messages and printed to a terminal, +the escape sequences are interpreted by the terminal emulator. This +could allow an attacker to manipulate terminal output (change colors, +set window title, clear screen) when an administrator views libinput +logs. + +Replace all control characters (0x00-0x1f and 0x7f) with '?' in +addition to the existing '%' escaping. This prevents terminal escape +sequence injection through device names in log output. + +Assisted-by: Claude:claude-opus-4-6 +(cherry picked from commit 71a2c5cae2a80a1e3bb29e3f3a07ccc3f3de5acb) + +Part-of: +--- + src/util-strings.h | 30 ++++++++++++++++++++++++------ + test/test-utils.c | 10 ++++++++++ + 2 files changed, 34 insertions(+), 6 deletions(-) + +--- a/src/util-strings.h ++++ b/src/util-strings.h +@@ -502,7 +502,10 @@ trunkname(const char *filename); + + /** + * Return a copy of str with all % converted to %% to make the string +- * acceptable as printf format. ++ * acceptable as printf format, and all non-NUL control characters ++ * (bytes 0x01-0x1f, 0x7f) replaced with '?' to prevent terminal ++ * escape sequence injection. NUL bytes are excluded implicitly ++ * because the string is null-terminated. + */ + static inline char * + str_sanitize(const char *str) +@@ -510,19 +513,34 @@ str_sanitize(const char *str) + if (!str) + return NULL; + +- if (!strchr(str, '%')) +- return strdup(str); +- + size_t slen = strlen(str); + slen = min(slen, 512); ++ ++ bool needs_sanitization = false; ++ for (size_t i = 0; i < slen; i++) { ++ unsigned char c = str[i]; ++ if (c == '%' || c < 0x20 || c == 0x7f) { ++ needs_sanitization = true; ++ break; ++ } ++ } ++ if (!needs_sanitization) ++ return strdup(str); ++ + char *sanitized = zalloc(2 * slen + 1); + const char *src = str; + char *dst = sanitized; + + for (size_t i = 0; i < slen; i++) { +- if (*src == '%') ++ unsigned char c = *src++; ++ if (c == '%') { ++ *dst++ = '%'; + *dst++ = '%'; +- *dst++ = *src++; ++ } else if (c < 0x20 || c == 0x7f) { ++ *dst++ = '?'; ++ } else { ++ *dst++ = c; ++ } + } + *dst = '\0'; + +--- a/test/test-utils.c ++++ b/test/test-utils.c +@@ -1459,6 +1459,16 @@ START_TEST(strsanitize_test) + { "x %", "x %%" }, + { "%sx", "%%sx" }, + { "%s%s", "%%s%%s" }, ++ { "\t", "?" }, ++ { "\n", "?" }, ++ { "\r", "?" }, ++ { "\x1b[31m", "?[31m" }, ++ { "foo\tbar", "foo?bar" }, ++ { "foo\nbar", "foo?bar" }, ++ { "\x01\x1f\x7f", "???" }, ++ { "clean", "clean" }, ++ { "a\x1b[0mb", "a?[0mb" }, ++ { "%\n", "%%?" }, + { NULL, NULL }, + }; +