Skip to content

coreutils: resolve utility names through symlink aliases - #15490

Open
limadog9 wants to merge 1 commit into
uutils:mainfrom
limadog9:fix/coreutils-symlink-aliases-10946
Open

limadog9 wants to merge 1 commit into
uutils:mainfrom
limadog9:fix/coreutils-symlink-aliases-10946

Conversation

@limadog9

@limadog9 limadog9 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

On Linux with glibc, resolve an unrecognized invocation name through one symlink lookup, including aliases found through PATH. This lets dummy -> true -> coreutils run true.

Add coverage for relative links, PATH lookup, argument forwarding, utility exit status, and unknown aliases.

Closes #10946.

Comment thread src/bin/coreutils.rs Outdated
};
// Follow each link separately: canonicalize would discard the utility name
// in an intermediate link such as dummy -> true -> coreutils.
for _ in 0..40 {

This comment was marked as resolved.

@limadog9
limadog9 force-pushed the fix/coreutils-symlink-aliases-10946 branch 2 times, most recently from f918ead to 7477559 Compare October 18, 2026 17:44
Comment thread src/bin/coreutils.rs Outdated
fn utility_from_symlink<T>(utils: &UtilityMap<T>, binary: &Path) -> Option<&'static str> {
use std::os::unix::fs::PermissionsExt;

// binary_path can return argv[0] on any Unix target; AT_EXECFN is not

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you restrict this to Linux and remove PATH lookup?

@limadog9
limadog9 force-pushed the fix/coreutils-symlink-aliases-10946 branch 2 times, most recently from 37d5117 to ad408e9 Compare October 18, 2026 18:08
Comment thread src/common/validation.rs Outdated
let execfn_bytes = execfn.to_bytes();
let exec_path = Path::new(OsStr::from_bytes(execfn_bytes));
let argv0 = args.next().unwrap();
let same_name = execfn_bytes.rsplit(|&b| b == b'/').next()

This comment was marked as resolved.

@limadog9
limadog9 force-pushed the fix/coreutils-symlink-aliases-10946 branch from ad408e9 to 6dfc6f7 Compare October 18, 2026 18:39
Comment thread tests/test_util_name.rs Outdated
target_env = "gnu",
feature = "true",
feature = "false",
feature = "echo"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need echo only.

@limadog9
limadog9 force-pushed the fix/coreutils-symlink-aliases-10946 branch 2 times, most recently from 0355994 to 72acd75 Compare October 18, 2026 19:02
@sylvestre

Copy link
Copy Markdown
Contributor

please also update the PR description: it says "On Unix" and "symlink chain", but the code does one readlink and only on linux glibc. thanks

Comment thread src/bin/coreutils.rs
return None;
}
utils
.keys()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is almost the same matching code as matched_util in main(), could be dedup, no?

Comment thread src/common/validation.rs
// the kernel reports /dev/fd/* and memfd_create/glibc's fallback /proc/self/fd/*
// argv0 is not full-path when called from PATH
// Otherwise keep the kernel path: argv0 may lack the directory after PATH lookup.
if execfn_bytes.rsplit(|&b| b == b'/').next() == argv0.as_bytes().rsplit(|&b| b == b'/').next()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't just a refactor: when the names match we now return execfn instead of argv0 and skip the shebang/proc checks, is that intended?

@oech3 oech3 Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Because we need full path.

Comment thread tests/test_util_name.rs Outdated
let at = &scene.fixtures;
at.mkdir("bin");
symlink_file(&scene.bin_path, at.plus("bin/echo")).unwrap();
for (index, target) in [std::path::PathBuf::from("bin/echo"), at.plus("bin/echo")]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two nested loops make this test hard to read, could you please write the cases out plainly?

Comment thread tests/test_util_name.rs Outdated

#[test]
#[cfg(all(target_os = "linux", target_env = "gnu", feature = "echo"))]
fn utility_alias_symlink_chain() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a test that dummy -> coreutils and dummy -> foo -> coreutils still fail with the not found error

@limadog9
limadog9 force-pushed the fix/coreutils-symlink-aliases-10946 branch from 72acd75 to 728cba7 Compare October 18, 2026 22:39
Comment thread tests/test_util_name.rs Outdated
#[test]
#[cfg(all(target_os = "linux", target_env = "gnu", feature = "echo"))]
fn utility_alias_without_path() {
use std::os::unix::process::CommandExt;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is almost the same as the relative_target_absolute_alias case, could be another case of the rstest above, no?

On Linux with glibc, resolve an unrecognized invocation name from its
immediate symlink target. Reuse binary_path's kernel invocation path,
retaining its full directory after PATH lookup.

Cover relative and absolute targets, shell PATH invocation, argument
forwarding, and invocation with PATH unset using echo.

Closes uutils#10946.
@limadog9
limadog9 force-pushed the fix/coreutils-symlink-aliases-10946 branch from 728cba7 to c4dc57b Compare October 19, 2026 19:38

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

coreutils: Resolve symlink with invalid binary name for better dummy support

3 participants