CVE-2026-35373
Executive Summary
CVE-2026-35373 identifies a logic error in the ln utility of the uutils coreutils project, a Rust-based reimplementation of standard Unix core utilities. The vulnerability manifests when ln is used in its target-directory form (e.g., ln SOURCE... DIRECTORY). While GNU coreutils treats all filenames as raw byte sequences, the uutils implementation enforces UTF-8 encoding validation on source paths. This causes the utility to fail when encountering valid Unix filenames containing non-UTF-8 bytes, resulting in a non-zero exit code and a local denial of service (DoS) condition for automated scripts or system tasks that rely on ln to process such filenames.
The vulnerability has a CVSS score of 3.3 (Low), reflecting its local attack vector and limited impact. No public exploit code or proof-of-concept is currently available, and the patch status remains unknown. The issue is primarily a behavioral divergence from GNU coreutils, which can break automation in environments with non-UTF-8 filenames.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the uutils coreutils project, which is distributed as a Rust crate (uu_ln) and is also available as a system package in some Linux distributions (e.g., via uutils-coreutils). The issue is not related to NPM, PyPI, Go, or Ruby ecosystems. However, any system or container image that replaces GNU coreutils with uutils coreutils is potentially affected. The supply chain risk is low, as the vulnerability only impacts local operations and does not introduce remote code execution or data exfiltration.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
- Base Score: 3.3 (Low)
- Attack Vector: Local (AV:L) – The attacker must have local access to the system.
- Attack Complexity: Low (AC:L) – No special conditions are required.
- Privileges Required: Low (PR:L) – The attacker needs a standard user account.
- User Interaction: None (UI:N) – No user action is required beyond running the vulnerable command.
- Scope: Unchanged (S:U) – The vulnerability does not affect other components.
- Confidentiality Impact: None (C:N) – No data exposure.
- Integrity Impact: None (I:N) – No data corruption.
- Availability Impact: Low (A:L) – The utility fails, causing a local denial of service for specific operations.
Threat Level: Low. The vulnerability is limited to local DoS and requires specific conditions (non-UTF-8 filenames). It is unlikely to be exploited in widespread attacks.
Deep Dive & Mechanics
The core issue lies in how uutils ln handles file paths. In Unix filesystems, filenames are sequences of bytes, and there is no requirement for them to be valid UTF-8. GNU coreutils ln treats all paths as raw byte strings, passing them directly to system calls like stat() and link(). In contrast, uutils ln (written in Rust) uses Rust's Path type, which internally assumes UTF-8 encoding on some platforms or performs UTF-8 validation when converting from OsStr to &str. When a source path contains non-UTF-8 bytes (e.g., a file named file\xff.txt), the conversion fails, and the utility returns an error without attempting the system call.
The vulnerable code path is in the target-directory form: ln SOURCE... DIRECTORY. When processing multiple sources, the utility iterates over each source path, attempts to convert it to a UTF-8 string, and if that fails, it prints an error and exits with a non-zero code. This prevents the creation of any links, even if other source paths are valid.
Root Cause: The use of Path::to_str() or similar methods that return Option<&str> and fail on non-UTF-8 input, instead of using Path::as_os_str() or OsStr methods that preserve raw bytes.
Vulnerable vs. Patched Code
Vulnerable Code (uutils ln):
// Pseudocode illustrating the issue
fn process_source(source: &Path) -> Result<(), Error> {
let source_str = source.to_str().ok_or(Error::NonUtf8Path)?;
// ... proceed with source_str
}
Patched Code (Expected Fix):
// Use OsStr to preserve raw bytes
fn process_source(source: &Path) -> Result<(), Error> {
let source_os = source.as_os_str();
// ... use source_os directly with system calls
}
The fix involves replacing UTF-8-dependent string operations with raw byte/OsStr operations, matching GNU coreutils behavior. As of this report, no official patch has been released.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Local access to a system with uutils coreutils installed (e.g.,
uutils-coreutilspackage). - Ability to create files with non-UTF-8 names (requires a filesystem that supports arbitrary bytes, e.g., ext4, XFS).
Exploitation Steps:
- Create a file with a non-UTF-8 name:
touch $'file\xff.txt' - Attempt to create a hard link using the target-directory form:
ln $'file\xff.txt' /tmp/ - Observe the failure:
ln: error: Invalid UTF-8 in path: 'file\xff.txt' - If an automated script relies on
lnto process such files, it will exit with a non-zero code, causing a local denial of service.
No public exploit code is available.
Blue Team
Detection:
- Monitor for
lncommands that exit with non-zero status and error messages containing "Invalid UTF-8". - Audit systems for the presence of uutils coreutils and compare behavior with GNU coreutils.
Prevention:
- Avoid using uutils coreutils in environments where non-UTF-8 filenames are common (e.g., legacy systems, internationalized environments).
- Use GNU coreutils as a drop-in replacement.
- If uutils is required, wrap
lncalls in scripts that handle non-UTF-8 paths gracefully (e.g., by usingfind -execwith raw byte handling).
Indicators of Compromise (IOCs)
- File System Artifacts: Files with non-UTF-8 names (e.g., containing bytes 0x80-0xFF).
- Log Entries: Error messages from
lncontaining "Invalid UTF-8" or "Non-UTF-8 path". - Process Behavior:
lnprocesses exiting with non-zero exit code when processing valid files. - System State: Incomplete or missing hard links in target directories.
Detection Engineering
YARA Rule
rule CVE_2026_35373_uutils_ln_utf8_error {
meta:
description = "Detects uutils ln error messages indicating non-UTF-8 path rejection"
author = "Valters IT"
date = "2026-01-01"
reference = "CVE-2026-35373"
strings:
$error1 = "Invalid UTF-8 in path" ascii wide nocase
$error2 = "Non-UTF-8 path" ascii wide nocase
$error3 = "path contains invalid UTF-8" ascii wide nocase
condition:
any of them
}
Sigma Rule
title: CVE-2026-35373 - uutils ln Non-UTF-8 Path Rejection
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects uutils ln utility failing due to non-UTF-8 filenames
author: Valters IT
date: 2026-01-01
logsource:
category: process_creation
product: linux
detection:
selection:
Image|endswith: '/ln'
CommandLine|contains: 'Invalid UTF-8'
condition: selection
falsepositives:
- Legitimate use of uutils ln with non-UTF-8 paths (rare)
level: low
tags:
- attack.t1499.001
- cve.2026.35373
Suricata Rule
alert syslog any any -> any any (msg:"CVE-2026-35373 - uutils ln Non-UTF-8 Path Rejection"; content:"Invalid UTF-8 in path"; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Mitigation:
- Replace uutils coreutils with GNU coreutils on affected systems:
sudo apt-get install coreutils # Debian/Ubuntu sudo yum install coreutils # RHEL/CentOS - If uutils must be used, modify scripts to handle non-UTF-8 paths by using
findwith-execand raw byte handling:find /path -type f -name '*[!-~]*' -exec ln {} /target/ \;
Long-Term Fix:
- Apply the upstream patch when available (monitor the uutils coreutils repository).
- Consider contributing a fix that uses
OsStrinstead of&strfor path handling.
Workaround:
- Avoid using the target-directory form of
lnwith files that may have non-UTF-8 names. Use the explicit formln SOURCE TARGETinstead.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Analyst
{/* [Security Hash: B07AABB6A9476E9F82B54E50] */}