Introduction
A missing input sanitization in libinput's udev helper lets a local attacker inject arbitrary udev properties and run commands as root, just by creating a virtual input device with a crafted name. On Linux desktops where packages like steam-devices or kdeconnectd grant unprivileged users access to /dev/uinput, this turns a seat user into root with little effort and high reliability.
libinput is the standard input handling library for nearly every modern Linux desktop environment, including GNOME, KDE Plasma, and Sway. Maintained under the freedesktop.org umbrella, it handles input device detection, event processing, and abstraction for both Wayland compositors and X.Org input drivers. Because it runs on essentially every Linux system with a graphical environment, a flaw in libinput can reach across the entire Linux desktop ecosystem.
Technical Information
Root Cause: CRLF Injection in udev Property Output
CVE-2026-50292 is classified as CWE-93 (Improper Neutralization of CRLF Sequences). CRLF injection usually comes up in the context of HTTP response splitting, but this vulnerability shows the same class of flaw at the Linux system level: the libinput-device-group udev helper reads the phys sysfs attribute of input devices and prints it straight into a KEY=VALUE udev property string with no escaping or sanitization.
The udev subsystem treats newline characters as property delimiters. When the phys value contains a \n character, udev splits the output into two separate KEY=VALUE pairs. The second pair becomes an entirely new udev property under the attacker's control.
Attack Flow
The exploitation chain runs through four stages:
Step 1: Malicious Device Creation. A local attacker creates a uinput device through the standard Linux uinput interface and sets its phys sysattr to contain a newline character via the UI_SET_PHYS ioctl. The phys value is crafted to include an injected udev property after the newline. For example, the value might be set to something like:
normal-value\nENV{REMOVE_CMD}="/path/to/malicious-script"
Step 2: Unsanitized Output. The libinput-device-group helper reads the raw phys value using udev_device_get_sysattr_value(d, "phys") and prints it directly as part of a udev property string. No escaping, filtering, or sanitization is applied to the value before output.
Step 3: Property Injection. When udev imports the output from libinput-device-group as environment variables, the newline character makes udev read the output as two separate KEY=VALUE pairs. The attacker-controlled second line is parsed as a legitimate udev property.
Step 4: Root Code Execution. By injecting the REMOVE_CMD udev property, the attacker specifies an arbitrary command that udev runs with root privileges when the malicious device is removed. Since the attacker controls both the device creation and removal, this gives a complete and deterministic local privilege escalation chain from seat user to root.
Privilege Requirements and Exploit Conditions
The critical gating factor is whether a non-root user can create uinput or uhid devices. By default, both /dev/uinput and /dev/uhid require root access. But several commonly installed packages on Fedora ship udev rules that grant uaccess to /dev/uinput:
| Device | Default Access | Packages Granting uaccess (Fedora) | Exploit Feasibility |
|---|---|---|---|
/dev/uinput | Root only | steam-devices, antimicrox, kdeconnectd | Feasible on gaming and multi device desktops |
/dev/uhid | Root only | No known packages ship uaccess rules | Requires root already; not useful for escalation |
On systems where any of these packages are installed, a user logged into a seat can create uinput devices without root privileges, so exploitation is straightforward. On systems without these uaccess rules, the attacker would already need root to create the malicious device, which removes the privilege escalation value entirely.
The Fix
The upstream fix in commit 76f0d8a7f57e2868882864b4611281f12f704b55 changes udev/libinput-device-group.c in two ways:
- The
const char *physpointer declaration becomes_autofree_ char *phys = NULL, a dynamically allocated sanitized string with automatic cleanup. - Both places where
physis assigned fromudev_device_get_sysattr_value(d, "phys")are wrapped with a newstr_sanitize()function:phys = str_sanitize(udev_device_get_sysattr_value(d, "phys")).
This sanitization strips or escapes newline and carriage return characters before the phys value goes into the udev property output, which stops the injection.
Affected Systems and Versions
The vulnerability affects:
- libinput versions before 1.30.4 (all prior releases in the 1.30.x branch)
- libinput 1.31.x versions before 1.31.3
Fixed versions are libinput 1.30.4 and libinput 1.31.3. Arch Linux already ships version 1.31.3-1 in its repositories.
The vulnerability is exploitable for privilege escalation specifically on systems where:
- A non-root user has seat access
- One of the following packages (or an equivalent) is installed, granting
uaccessto/dev/uinput:steam-devices,antimicrox, orkdeconnectd - Fedora is the most explicitly documented distribution with these conditions, though other distributions shipping similar udev rules may also be affected
Systems without uinput uaccess rules (servers, minimal installations, desktops without gaming or device bridging software) carry much lower risk, since the attacker would already need root to create the malicious device.
Vendor Security History
The 2026 calendar year has been busy for libinput security disclosures, with three distinct CVEs published in roughly two months:
| CVE | Disclosure Date | Type | Description |
|---|---|---|---|
| CVE-2026-35093 | April 2026 | Sandbox escape | Lua plugin loader accepts pre-compiled bytecode without verification, bypassing the Lua sandbox |
| CVE-2026-35094 | April 2026 | Use after free | Dangling pointer in Lua plugin handling enables information disclosure |
| CVE-2026-50292 | June 2026 | CRLF injection | Unescaped phys output in udev helper enables root code execution |
The two April CVEs both involved the Lua plugin system introduced in libinput 1.30. CVE-2026-35093 was a sandbox escape where the plugin loader accepted pre-compiled Lua bytecode without runtime verification, allowing unrestricted access at the process privilege level. CVE-2026-35094 was a use after free in the Lua plugin handling that could enable information disclosure. SUSE tracked both CVEs across its product line, confirming impact on SLE and openSUSE distributions.
Before 2026, libinput had a relatively clean security record with few public CVEs. Three security issues in two months suggests that the Lua plugin system and the weak input validation in the udev helper opened new attack surface that was not audited well enough before release. The common thread across all three is a lack of defense in depth: trust boundaries were not enforced at the point where external data entered security critical processing paths.
The vendor response to CVE-2026-50292 was prompt. The oss-security advisory went out the same day as the NVD entry (June 4, 2026), the fix was already committed upstream, and patched versions (1.30.4 and 1.31.3) were available at the same time. The advisory gives clear information about exploit conditions, affected versions, and the specific packages that create elevated risk configurations on Fedora, which lets administrators make informed risk assessments.
Mitigation Recommendations
Immediate Actions
-
Upgrade libinput to version 1.30.4 or 1.31.3 (or later). Check your current version with
libinput --versionor your distribution's package manager. -
Audit uinput uaccess rules. On Fedora and possibly other distributions, check whether
steam-devices,antimicrox, orkdeconnectdare installed. If you do not need them, removing them eliminates the most accessible attack vector. If you do need them, know that they let seat users create uinput devices. -
Review custom udev rules. Any custom rules granting
uaccessto/dev/uinputor/dev/uhidcreate exploitable configurations.
Defense in Depth
-
Restrict REMOVE_CMD. Where it is operationally feasible, disable or restrict the
REMOVE_CMDudev property mechanism, which is the direct root execution path in this exploit chain. -
Monitor uinput device creation. Log uinput device creation by non-root users. Unexpected uinput devices with unusual
physattributes are a strong sign of exploitation attempts. -
Backport the fix if packages are unavailable. For distributions that have not yet released patched packages, the upstream commit
76f0d8a7provides the reference implementation of thestr_sanitize()approach.
Prioritization
Patch desktop systems with steam-devices or similar uaccess granting packages immediately, especially those with untrusted seat users. Server or minimal systems without uinput uaccess rules can be upgraded on a normal patch cycle.
Threat Intelligence
As of the disclosure date (June 4, 2026), there is no confirmed evidence of active exploitation of CVE-2026-50292. The vulnerability was disclosed responsibly through the oss-security mailing list with fixes already available, consistent with coordinated disclosure. No entries in CISA's Known Exploited Vulnerabilities catalog reference this CVE.
Several factors suggest it is likely to attract threat actor interest:
- Low attack complexity. The exploit needs only the ability to create a uinput device with a crafted
physstring, which is straightforward on systems with the right uaccess rules. - Deterministic execution. The
REMOVE_CMDmechanism gives reliable root code execution, not a probabilistic memory corruption exploit that might fail or crash the system. - Existing precedent. A September 2024 threat intelligence report documented Linux malware exploiting udev rules for persistence and privilege escalation, which confirms that udev is a known and actively targeted attack surface.
- Large vulnerable population. Systems with Steam installed via
steam-devicesare a large desktop population that may not get timely security updates.
The most likely threat actor profiles include local privilege escalation toolchain developers, insider threats on shared Linux desktops, and APT groups targeting developer workstations where they already have local access and need reliable privilege escalation.
Broader Implications
This vulnerability points to an architectural concern: the REMOVE_CMD udev property is a direct execution path with root privileges, and because it can be set through imported output, it is a high value target for injection attacks. Hardening udev itself to limit which properties can be set through imported output would add a second layer of defense beyond sanitizing individual data sources.
The three libinput CVEs in 2026 also point to a need for a holistic security review of the project's architecture. The Lua plugin system (CVE-2026-35093, CVE-2026-35094) and the udev helper code (CVE-2026-50292) are both cases where data from external sources was processed without enough sanitization before being used in a security sensitive context. Organizations relying on libinput should re-evaluate the project's security posture rather than treat each disclosure as an isolated event.
References
- NVD: CVE-2026-50292
- oss-security: libinput-device-group unescaped phys output can inject udev properties
- GitLab Commit: libinput-device-group: sanitize phys before printing it (76f0d8a7)
- GitLab Issue: libinput-device-group unescaped phys output (#1296)
- libinput Project Page: freedesktop.org
- CWE-93: Improper Neutralization of CRLF Sequences
- Arch Linux: libinput 1.31.3-1 Package
- Phoronix: Libinput Hit By Worrying Security Issues With Its Lua Plugins
- NVD: CVE-2026-35093
- SUSE: CVE-2026-35093
- SUSE: CVE-2026-35094
- Red Hat Bugzilla: CVE-2026-35094
- SISA: New Linux Malware Exploits Udev Rules
- CISA: Known Exploited Vulnerabilities Catalog
- Repology: libinput Package Versions



