coreutils icon indicating copy to clipboard operation
coreutils copied to clipboard

rm:fix safe traversal/access

Open mattsu2020 opened this issue 3 weeks ago • 14 comments

Modify path control to enable secure access

related https://github.com/uutils/coreutils/issues/9542

mattsu2020 avatar Dec 06 '25 03:12 mattsu2020

CodSpeed Performance Report

Merging #9577 will improve performances by 14.61%

Comparing mattsu2020:rm_fix_full_path (a647f9c) with main (5b261bc)

Summary

⚡ 1 improvement
✅ 126 untouched
⏩ 6 skipped[^skipped]

Benchmarks breakdown

Benchmark BASE HEAD Change
rm_recursive_tree 13.6 ms 11.9 ms +14.61%
[^skipped]: 6 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

codspeed-hq[bot] avatar Dec 06 '25 03:12 codspeed-hq[bot]

GNU testsuite comparison:

Skip an intermittent issue tests/misc/tee (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/tail/overlay-headers (passes in this run but fails in the 'main' branch)

github-actions[bot] avatar Dec 06 '25 03:12 github-actions[bot]

Similar to #9554, it hits file descriptor limits:

$ mkdir -p `python3 -c 'print("a/" * 1024 * 16)'`
$ ./target/debug/rm -rf a
rm: cannot remove '[long file name snipped]': Directory not empty
$ strace ./target/debug/rm -rf a
[...]
newfstatat(1022, "a", {st_mode=S_IFDIR|0755, st_size=2, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(1022, "a", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 1023
dup(1023)                               = -1 EMFILE (Too many open files)
unlinkat(1022, "a", AT_REMOVEDIR)       = -1 ENOTEMPTY (Directory not empty)
[...]

collinfunk avatar Dec 06 '25 04:12 collinfunk

Similar to #9554, it hits file descriptor limits:

$ mkdir -p `python3 -c 'print("a/" * 1024 * 16)'`
$ ./target/debug/rm -rf a
rm: cannot remove '[long file name snipped]': Directory not empty
$ strace ./target/debug/rm -rf a
[...]
newfstatat(1022, "a", {st_mode=S_IFDIR|0755, st_size=2, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(1022, "a", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 1023
dup(1023)                               = -1 EMFILE (Too many open files)
unlinkat(1022, "a", AT_REMOVEDIR)       = -1 ENOTEMPTY (Directory not empty)
[...]

We need to make a fix to prevent the file from opening continuously.

mattsu2020 avatar Dec 06 '25 04:12 mattsu2020

GNU testsuite comparison:

GNU test failed: tests/du/long-from-unreadable. tests/du/long-from-unreadable is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/pwd/pwd-long. tests/pwd/pwd-long is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/deep-2. tests/rm/deep-2 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/many-dir-entries-vs-OOM. tests/rm/many-dir-entries-vs-OOM is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/rm/rm1 (passes in this run but fails in the 'main' branch)

github-actions[bot] avatar Dec 06 '25 05:12 github-actions[bot]

GNU testsuite comparison:

GNU test failed: tests/du/long-from-unreadable. tests/du/long-from-unreadable is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/pwd/pwd-long. tests/pwd/pwd-long is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/deep-2. tests/rm/deep-2 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/many-dir-entries-vs-OOM. tests/rm/many-dir-entries-vs-OOM is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/rm/rm1 (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/overlay-headers (passes in this run but fails in the 'main' branch)

github-actions[bot] avatar Dec 06 '25 05:12 github-actions[bot]

GNU testsuite comparison:

GNU test failed: tests/du/long-from-unreadable. tests/du/long-from-unreadable is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/pwd/pwd-long. tests/pwd/pwd-long is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/deep-2. tests/rm/deep-2 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/many-dir-entries-vs-OOM. tests/rm/many-dir-entries-vs-OOM is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/rm/rm1 (passes in this run but fails in the 'main' branch)

github-actions[bot] avatar Dec 06 '25 05:12 github-actions[bot]

GNU testsuite comparison:

GNU test failed: tests/du/long-from-unreadable. tests/du/long-from-unreadable is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/pwd/pwd-long. tests/pwd/pwd-long is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/deep-2. tests/rm/deep-2 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/many-dir-entries-vs-OOM. tests/rm/many-dir-entries-vs-OOM is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/rm/rm1 (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/overlay-headers (passes in this run but fails in the 'main' branch)

github-actions[bot] avatar Dec 06 '25 06:12 github-actions[bot]

GNU testsuite comparison:

GNU test failed: tests/du/long-from-unreadable. tests/du/long-from-unreadable is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/pwd/pwd-long. tests/pwd/pwd-long is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/deep-2. tests/rm/deep-2 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/many-dir-entries-vs-OOM. tests/rm/many-dir-entries-vs-OOM is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/rm/rm1 (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/overlay-headers (passes in this run but fails in the 'main' branch)

github-actions[bot] avatar Dec 06 '25 07:12 github-actions[bot]

i am confused, why do you create a PR with 24 commits ? why not waiting for this to be ok before creating the PR ? thanks

sylvestre avatar Dec 06 '25 08:12 sylvestre

i am confused, why do you create a PR with 24 commits ? why not waiting for this to be ok before creating the PR ? thanks

I attempted to address the file descriptor limitations, but it seems significant modifications are required. After making the necessary changes as a draft, I will request another review.

mattsu2020 avatar Dec 06 '25 09:12 mattsu2020

GNU testsuite comparison:

GNU test failed: tests/du/long-from-unreadable. tests/du/long-from-unreadable is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/pwd/pwd-long. tests/pwd/pwd-long is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/deep-2. tests/rm/deep-2 is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/rm/many-dir-entries-vs-OOM. tests/rm/many-dir-entries-vs-OOM is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/rm/rm1 (passes in this run but fails in the 'main' branch)

github-actions[bot] avatar Dec 06 '25 10:12 github-actions[bot]

GNU testsuite comparison:

Congrats! The gnu test tests/du/files0-from is no longer failing!

github-actions[bot] avatar Dec 06 '25 10:12 github-actions[bot]

The file descriptor issue will be addressed in a separate pull request, so I've reverted it.

mattsu2020 avatar Dec 06 '25 10:12 mattsu2020