CVE-2026-35372
Description
A logic error in the ln utility of uutils coreutils allows the utility to dereference a symbolic link target even when the --no-dereference (or -n) flag is explicitly provided. The implementation previously only honored the "no-dereference" intent if the --force (overwrite) mode was also enabled. This flaw causes ln to follow a symbolic link that points to a directory and create new links inside that target directory instead of treating the symbolic link itself as the destination. In environments where a privileged user or system script uses ln -n to update a symlink, a local attacker could manipulate existing symbolic links to redirect file creation into sensitive directories, potentially leading to unauthorized file creation or system misconfiguration.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
coreutilscrates.io | < 0.8.0 | 0.8.0 |
Affected products
2Patches
1394c4b17f2f3ln: Avoid dereferencing target if --no-dereference is passed.
2 files changed · +58 −22
src/uu/ln/src/ln.rs+36 −22 modified@@ -294,30 +294,44 @@ fn link_files_in_dir(files: &[PathBuf], target_dir: &Path, settings: &Settings) let mut all_successful = true; for srcpath in files { - let targetpath = if settings.no_dereference - && matches!(settings.overwrite, OverwriteMode::Force) - && target_dir.is_symlink() - { - // In that case, we don't want to do link resolution - // We need to clean the target - if target_dir.is_file() { - if let Err(e) = fs::remove_file(target_dir) { - show_error!( - "{}", - translate!("ln-error-could-not-update", "target" => target_dir.quote(), "error" => e) - ); + let targetpath = if settings.no_dereference && target_dir.is_symlink() { + let remove_target = || -> UResult<()> { + // In that case, we don't want to do link resolution + // We need to clean the target + if target_dir.is_file() { + if let Err(e) = fs::remove_file(target_dir) { + show_error!( + "{}", + translate!("ln-error-could-not-update", "target" => target_dir.quote(), "error" => e) + ); + } } - } - #[cfg(windows)] - if target_dir.is_dir() { - // Not sure why but on Windows, the symlink can be - // considered as a dir - // See test_ln::test_symlink_no_deref_dir - if let Err(e) = fs::remove_dir(target_dir) { - show_error!( + #[cfg(windows)] + if target_dir.is_dir() { + // Not sure why but on Windows, the symlink can be + // considered as a dir + // See test_ln::test_symlink_no_deref_dir + if let Err(e) = fs::remove_dir(target_dir) { + show_error!( + "{}", + translate!("ln-error-could-not-update", "target" => target_dir.quote(), "error" => e) + ); + } + } + Ok(()) + }; + match settings.overwrite { + OverwriteMode::NoClobber => {} + OverwriteMode::Interactive => { + if prompt_yes!( "{}", - translate!("ln-error-could-not-update", "target" => target_dir.quote(), "error" => e) - ); + translate!("ln-prompt-replace", "file" => target_dir.quote()) + ) { + remove_target()?; + } + } + OverwriteMode::Force => { + remove_target()?; } } target_dir.to_path_buf()
tests/by-util/test_ln.rs+22 −0 modified@@ -1043,3 +1043,25 @@ fn test_ln_backup_no_path_traversal() { assert!(at.file_exists("b~")); assert!(!at.plus("b~").is_symlink()); } + +#[test] +fn test_ln_no_dereference_symbolic() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + at.mkdir("a"); + at.symlink_dir("a", "b"); + at.touch("x"); + scene + .ucmd() + .args(&["-n", "x", "b"]) + .fails() + .stderr_contains("Already exists"); + assert!(!at.file_exists("a/x")); + #[cfg(not(target_os = "android"))] + { + scene.ucmd().args(&["-bn", "x", "b"]).succeeds(); + assert!(!at.file_exists("a/x")); + assert!(at.file_exists("b")); + assert!(at.is_symlink("b~")); + } +}
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/uutils/coreutils/pull/11253nvdIssue TrackingPatchWEB
- github.com/advisories/GHSA-wq63-vh5h-pr5pghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-35372ghsaADVISORY
- github.com/uutils/coreutils/commit/394c4b17f2f382b4be9f54389bcb79028de02f39ghsaWEB
- github.com/uutils/coreutils/releases/tag/0.8.0nvdRelease NotesWEB
News mentions
0No linked articles in our index yet.