Jul 6, 2026·7 min read·18 visits
A logical flow-control bypass and a TOCTOU race condition in the uutils coreutils mkfifo utility allow unprivileged local attackers to degrade system file permissions and escalate privileges.
CVE-2026-35341 is a high-severity vulnerability in the mkfifo utility of uutils coreutils, involving a logic-flow bypass and a TOCTOU race condition that permits unauthorized file permission degradation and privilege escalation.
uutils coreutils is a cross-platform implementation of the GNU coreutils suite written in Rust. Because Rust provides strong memory safety guarantees, these tools are increasingly deployed in performance-critical, containerized, or minimal environments such as Wolfi and Chainguard images. However, memory safety does not preclude systemic logical flaws, which can still compromise security boundaries.
This analysis focuses on CVE-2026-35341, a high-severity vulnerability affecting the mkfifo utility (uu_mkfifo applet) within uutils coreutils. The issue involves a logical flow-control error combined with a Time-of-Check to Time-of-Use (TOCTOU) race condition during file permission assignment. An unprivileged local attacker can exploit these issues to alter permissions of arbitrary files on the local filesystem, leading to potential local privilege escalation (LPE).
The primary root cause resides within the directory-processing loop in src/uu/mkfifo/src/mkfifo.rs. When multiple file paths are provided to the utility, a loop iterates over each path, calling the create_fifo helper function. The utility expects to create a new named pipe (FIFO) at each location and subsequently apply the configured permissions.
If the specified path already exists, the operating system kernel returns an EEXIST error, which create_fifo bubbles up. The error handling mechanism of mkfifo catches this exception, logs an error message to the standard error console, but fails to stop processing for that specific iteration. Because there is no continue statement inside the Err match branch, execution drops directly into the subsequent permission-setting logic.
The application then calls fs::set_permissions(path, mode) on the user-supplied target. Since the target file already exists and the caller may own it (or have administrative permissions), the system applies the newly requested permissions—or fallback default permissions—directly to the existing file. This allows standard system files or user-owned configuration documents to be silently modified to a degraded security state.
Beyond the simple control flow issue, the implementation of mkfifo is subject to a classic Time-of-Check to Time-of-Use (TOCTOU) vulnerability. This race condition arises from the split-second delay between the verification/creation stage and the modification stage. These operations are performed non-atomically via distinct system calls.
First, the program invokes create_fifo(path) to verify and create the FIFO. Once completed, the program resolves the path a second time to execute the set_permissions routine. Because this secondary modification operates on a path string rather than an active file descriptor, an attacker with write access to the parent directory can swap the newly created FIFO with a symbolic link before the permission phase occurs.
Since standard Rust file-system APIs (such as std::fs::set_permissions) resolve symbolic links by default, the kernel traverses the attacker's symlink. This redirects the permission modification to a target file outside the immediate directory, such as a critical system file. The lack of lchmod or descriptor-locked controls makes this sequence highly exploitable in shared environments.
The vulnerable code structure in src/uu/mkfifo/src/mkfifo.rs fails to interrupt the program flow upon encountering a creation failure. The block below represents the logical flaw prior to the introduction of the patch:
// Vulnerable Implementation
for path in &paths {
match create_fifo(path) {
Ok(_) => {
// FIFO created successfully
}
Err(e) => {
// Log the EEXIST or other error to stderr
show_error!("{}", e);
// Missing control flow redirect (continue) allows execution to proceed
}
}
// Execution falls through and alters target permissions
if let Some(mode) = specified_mode {
fs::set_permissions(path, mode);
} else {
fs::set_permissions(path, default_mode);
}
}The patch introduced in Pull Request #10376 inserts the missing control loop redirection, ensuring that if create_fifo returns an error, the iteration terminates immediately. The following block displays the corrected code:
// Patched Implementation
for path in &paths {
if let Err(e) = create_fifo(path) {
// Log the error to stderr as before
show_error!("{}", e);
// Patch: Terminate current iteration, bypassing permission-setting
continue;
}
// This section is now unreachable if creation failed
if let Some(mode) = specified_mode {
fs::set_permissions(path, mode);
}
}While the introduction of the continue statement resolves the logical fall-through for existing paths, it is critical to note that the TOCTOU symlink race condition persists if a user executes mkfifo on non-existing paths inside a shared directory. A robust resolution requires utilizing file-descriptor-based routines (such as fchmod) or configuring open-flags like O_NOFOLLOW on systems that support it to prevent the utility from traversing newly planted symbolic links.
Exploitation of the logical fall-through does not require complex scripting. In a typical scenario, a system administrator or an automated script runs mkfifo on a list of files that include sensitive files like private keys. For instance, if an administrator executes mkfifo -m 0644 /home/user/.ssh/id_rsa, the utility prints an error but modifies the SSH key permissions from 0600 to 0644, exposing the private key to all local users.
To exploit the TOCTOU symlink race, an attacker requires local shell access and the ability to write to a directory where a privileged user runs mkfifo. A script can continuously monitor the directory, waiting for the target FIFO path to be initialized, and immediately swap it for a symlink pointing to /etc/shadow.
The timing window is highly reachable on standard Linux multi-core environments. If the attacker wins the race, the privileged process changes the permissions of /etc/shadow to world-writable (e.g., 0666), enabling the unprivileged attacker to modify system credentials and obtain root privileges.
The security impact of CVE-2026-35341 is classified as high. The primary consequences are unauthorized modification of system-wide file permissions and local privilege escalation. Because core utilities are foundational elements of Unix-like operating systems, any vulnerability in these binaries can undermine the security posture of the entire platform.
The CVSS 3.1 base score of 7.1 highlights the severity of this weakness. The Confidentiality and Integrity metrics are both rated as High because an attacker can read sensitive files by lowering permissions and write to critical files like /etc/shadow to alter system-level configurations.
In cloud-native or containerized environments, degrading permissions on critical configuration files or secrets mounted into shared volumes can lead to container escape or database credential theft. The vulnerability's presence in standard base images increases the overall threat surface across development pipelines.
Remediating this vulnerability requires immediate updates to uutils coreutils. Users should verify that their systems run a version containing the changes introduced in Pull Request #10376. This update prevents the logical fall-through by skipping the permission-setting phase on creation failures.
For systems where immediate updates are not possible, administrators should implement strict operational controls. Avoid running mkfifo as root or inside world-writable directories such as /tmp. Instead, utilize secure subdirectories with permissions restricted to the executing user (e.g., 0700).
Furthermore, deploying kernel-level protections can mitigate symlink exploitation. In Linux environments, setting the sysctl option fs.protected_symlinks to 1 prevents users from following symlinks in world-writable sticky directories if the symlink's owner does not match the accessor, effectively blocking the TOCTOU attack vector.
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
coreutils uutils | < commit pull/10376 | PR #10376 merged version |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-732 |
| Attack Vector | Local (AV:L) |
| CVSS v3.1 Score | 7.1 |
| EPSS Score | 0.00165 |
| Exploit Status | Proof of Concept (PoC) Available |
| CISA KEV Status | Not Listed |
The software specifies permissions for a security-critical resource in a way that allows that resource to be accessed by unintended actors.
Grav CMS prior to version 1.7.53 and 2.0.0-rc.8 is vulnerable to an unauthenticated remote denial of service (DoS) vulnerability. By supplying crafted query parameters with extremely large dimensions to image assets, remote unauthenticated attackers can force the server to allocate massive amounts of system memory, leading to kernel Out-Of-Memory (OOM) termination of web worker processes.
CVE-2026-53657 is a local privilege escalation vulnerability in Lima (lima-vm/lima) affecting versions prior to 2.1.3 when configured with the QEMU driver. The guest agent daemon, running as root, creates its communication socket `/run/lima-guestagent.sock` with world-writable permissions (0777). This allows unprivileged local users to command the agent to establish arbitrary tunnels, including to privileged local UNIX sockets (like D-Bus). Because the target daemon authenticates the incoming connection using the credentials of the root-owned guest agent (via SO_PEERCRED), unprivileged users can perform root operations, resulting in complete guest VM compromise.
An unauthenticated Denial of Service vulnerability exists in the s2n-quic library's CryptoStream reassembler due to a lack of buffer limits on out-of-order cryptographic frames. An attacker can transmit a crafted CRYPTO frame with an extremely high offset and nominal payload, forcing the receiver to execute unbounded memory allocations and causing service crashes.
A JNDI Injection and Deserialization Gadget vulnerability exists in mchange-commons-java prior to version 0.6.0. The com.mchange.v2.naming.JavaBeanObjectFactory component permits arbitrary class instantiation and setter invocation, allowing attackers to perform Server-Side Request Forgery (SSRF) and remote class loading.
SurrealDB versions supporting element-level SELECT permissions on arrays are vulnerable to a logical authorization bypass. Due to an index-shifting error during array filtration, restricted elements can skip permission checks and leak to unauthorized record users.
CVE-2026-12243 is a path traversal vulnerability in the Natural Language Toolkit (NLTK) version 3.9.4. The flaw exists because the input validation routine fails to account for percent-encoded directory traversal sequences like '..%2f' before passing them to urllib.request.url2pathname(), which decodes them into active traversal sequences.