A local attacker with /dev/uinput access can inject arbitrary udev properties through the libinput-device-group helper. Depending on downstream udev rules, this can result in root code execution (e.g. via injected REMOVECMD properties executed at device removal time). REMOVECMD is in the default udev rules and expected to be present on virtually all machines.
A flaw was found in libinput. A local attacker who can place a specially crafted Lua bytecode file in certain system or user configuration directories can bypass security restrictions. This allows the attacker to run unauthorized code with the same permissions as the program using libinput, such as a graphical compositor. This could lead to the attacker monitoring keyboard input and sending that information to an external location.
On Thu, Jun 04, 2026 at 08:12:22PM +1000, Peter Hutterer wrote: ========================================= libinput Security Advisory: June 4, 2026 =========================================
An issue has been found in libinput:
1) libinput-device-group unescaped phys output can inject udev properties leading to arbitrary root code execution
libinput uses a udev helper called libinput-device-group. This helper uses a device's phys sysattr as one element of a udev property value which is printed as a KEY=VALUE pair and imported as ENV by udev.
A malicious uinput or uhid device that sets a phys sysattr containing \n caused the output to be interpreted as two separate KEY=VALUE pairs by udev. This could cause arbitrary execution as root (e.g. by setting the REMOVECMD property).
A CVE has been requested for this issue but did not get assigned in time for this disclosure.
Upstream issue: https://gitlab.freedesktop.org/libinput/libinput/-/workitems/1296 Upstream fix: https://gitlab.freedesktop.org/libinput/libinput/-/commit/76f0d8a7f57e2868882864b4611281f12f704b55 Versions affected: libinput <= 1.31.2 and <= 1.30.3 Fixed versions: libinput 1.31.3, 1.30.4 This issue has now been assigned CVE-2026-50265
Cheers, Peter
========================================= libinput Security Advisory: June 4, 2026 =========================================
An issue has been found in libinput:
1) libinput-device-group unescaped phys output can inject udev properties leading to arbitrary root code execution
libinput uses a udev helper called libinput-device-group. This helper uses a device's phys sysattr as one element of a udev property value which is printed as a KEY=VALUE pair and imported as ENV by udev.
A malicious uinput or uhid device that sets a phys sysattr containing \n caused the output to be interpreted as two separate KEY=VALUE pairs by udev. This could cause arbitrary execution as root (e.g. by setting the REMOVECMD property).
A CVE has been requested for this issue but did not get assigned in time for this disclosure.
Upstream issue: https://gitlab.freedesktop.org/libinput/libinput/-/workitems/1296 Upstream fix: https://gitlab.freedesktop.org/libinput/libinput/-/commit/76f0d8a7f57e2868882864b4611281f12f704b55 Versions affected: libinput <= 1.31.2 and <= 1.30.3 Fixed versions: libinput 1.31.3, 1.30.4
Affected distributions/compositors: -----------------------------------
Affected are libinput versions 1.31.2 and 1.30.3 and all earlier versions.
To exploit this vulnerability an attacker needs to create a malicious uinput or uhid device.
uinput is typically restricted to root but may be tagged with uaccess by custom udev rules. On Fedora, the following packages ship such a rule: steam-devices, antimicrox and kdeconnectd. If any of these packages are installed, uinput devices can be created by the user logged into a seat.
uhid is typically restricted to root. I am not aware of packages shipping udev rules that provide uaccess to /dev/uhid.
Acknowledgements ----------------
Many thanks to Csome for reporting this issue.
An attacker that can deploy a pre-compiled lua bytecode file in {/usr/share,/etc}/libinput/plugins and/or XDGCONFIGHOME/libinput/plugins can run unrestricted code in the process that uses libinput, typically the compositor. Lua bytecode is not verified at runtime and the sandboxing restrictions are no longer in effect. This allows an attacker to monitor any keyboard events and send those to an external destination and/or execute virtually any code under the calling process' privileges. For the exploit to work, lua plugins must be enabled in libinput and loaded by the compositor. If libinput is compiled with -Dautoload-plugins any plugin is loaded automatically (Fedora 43 and 44). The XDGCONFIGHOME directory is only loaded if enabled by the compositor (e.g. mutter 50 does this). The attacker must be able to deploy a lua plugin in one of the directories loaded by libinput.
A flaw was found in libinput. An attacker capable of deploying a Lua plugin file in specific system directories can exploit a dangling pointer vulnerability. This occurs when a garbage collection cleanup function is called, leaving a pointer that can then be printed to system logs. This could potentially expose sensitive data if the memory location is re-used, leading to information disclosure. For this exploit to work, Lua plugins must be enabled in libinput and loaded by the compositor.
========================================= libinput Security Advisory: April 2, 2026 =========================================
Multiple issues have been found in libinput:
1) CVE-2026-35093: Sandbox escape in libinput plugins
The libinput plugin system provides a sandbox to any Lua plugins to restrict them from any IO other than log messages. However, a bug in the plugin system loader allowed for precompiled byte-code to be loaded. This bytecode is not verified at runtime and thus not restricted by the sandbox. This allows a plugin to do basically anything Lua allows, at the process' privilege level. An attacker that manages to deploy such a Lua plugin may thus have unrestricted access to the machine (depending on user privileges).
Upstream issue: https://gitlab.freedesktop.org/libinput/libinput/-/workitems/1271 Upstream fix: https://gitlab.freedesktop.org/libinput/libinput/-/commit/356c498fd4ba25ec99f6866fc96847ec3d1f16bf Versions affected: libinput 1.31.0, libinput 1.30.[0-2] Fixed versions: libinput 1.31.1, libinput 1.30.3
2) CVE-2026-35094: Use after free allowing information leak in libinput plugins
This issue is less severe: a plugin that called Lua's gc() function left a dangling pointer in the device's name which could be printed to the log. Depending on the value at the memory location, this could lead to sensitive information being exposed.
Upstream issue: https://gitlab.freedesktop.org/libinput/libinput/-/workitems/1272 Upstream fix: https://gitlab.freedesktop.org/libinput/libinput/-/commit/45dfd0f0301af855f068df27b2e40cc9f5713acd Versions affected: libinput 1.31.0, libinput 1.30.[0-2] Fixed versions: libinput 1.31.1, libinput 1.30.3
As noted above, updated libinput packages that fix these issues have been released.
Affected distributions/compositors: -----------------------------------
Affected is any distribution with libinput 1.30.0 and newer, however lua plugins are only loaded if the compositor (or another caller) loads plugins. This is currently the case for GNOME 50's mutter, KWin (git) and Niri (git). wlroots, sway and river are not affected.
Distributions affected: Fedora 43 and Fedora 44. Fedora enables the -Dautoload-plugins meson option which causes plugins to be loaded regardless of compositor support. Arch, OpenSuSE, Ubuntu, Debian and NixOS do not set this flag and/or are on older versions of libinput.
This is not an exhaustive list of distributions or compositors. There are a number of utilities that use libinput and may be affected by this, in particular those run as root.
Acknowledgements ----------------
Many thanks to Koen Tange for reporting this issue.
An attacker that can deploy a lua file {/usr/share,/etc}/libinput/plugins and possibly XDGCONFIGHOME/libinput/plugins can call a GC cleanup function and leave a dangling pointer. This pointer can then be printed to the system logs, potentially exposing sensitive data once the memory location is re-used. For the exploit to work, lua plugins must be enabled in libinput and loaded by the compositor. If libinputis compiled with -Dautoload-plugins any plugin is loaded automatically (Fedora 43 and 44). The XDGCONFIGHOME directory is only loaded if enabled by the compositor (e.g. mutter 50 does this). The attacker must be able to deploy a lua plugin in one of the directories loaded by libinput.