Skip to content

mv: symlink exponential walk fix - #14286

Open
mtvb wants to merge 3 commits into
uutils:mainfrom
mtvb:symlink_exponential_walk_fix
Open

mv: symlink exponential walk fix#14286
mtvb wants to merge 3 commits into
uutils:mainfrom
mtvb:symlink_exponential_walk_fix

Conversation

@mtvb

@mtvb mtvb commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

scan_directory_recursive decides recursion with path.is_dir(), which follows symlinks.
Two ln -s .. symlinks branch *2 per level down to the kernel's 40-symlink ELOOP limit, creating 2^40 paths.

Fix: Decide recursion from symlink_metadata() instead of path.is_dir(), so the scanner never descends through a symlink. Since the else branch already called symlink_metadata(), it means no extra syscall - the metadata is now fetched once and used for both the recursion decision and the grouping check.

Fixes #14285

Comment thread src/uu/mv/src/hardlink.rs Outdated

if path.is_dir() {
// never descend through a symlink.
let metadata = path.symlink_metadata()?;

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.

entry.file_type() answers the is-a-directory question straight from readdir's d_type with no syscall on Linux; you only need symlink_metadata() on the non-directory branch for nlink/dev/ino.

@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown

Binary size comparison:

Individual binary size comparison VS main (threshold: >=5% AND >=4 KB).

Total size of compared binaries: 152.20 MB (+1016 KB, +0.66%)

Significant per-binary changes:
  comm     1.12 MB ->    2.33 MB  (+1.21 MB, +107.29%)

@mtvb

mtvb commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

I was unsure about the is_file() branch cause one of my tests failed. My test was faulty, entry.metadata() is fine for files.

@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/tail/tail-n0f is now passing!

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.

mv: two self-referential symlinks cause very long runtime

2 participants