uucore: add safe_copy module with TOCTOU-resistant copy primitives#12130
Merged
Conversation
Three patches in flight (cp uutils#10011, cp uutils#10017, mv uutils#10014) each independently reinvent the same security primitive: open the source with optional O_NOFOLLOW, create the destination with a restrictive 0o600 initial mode, copy bytes, and let the caller fix permissions later. The cp variants ship duplicated across platform/{linux, other_unix}.rs; mv hand-rolls a similar block in rename_file_fallback and notably forgets the O_NOFOLLOW guard. Add a single home for the primitive: pub fn open_source(path, nofollow) -> io::Result<File> pub fn create_dest_restrictive(path, nofollow) -> io::Result<File> pub fn safe_copy_file(src, dst, nofollow) -> io::Result<u64> The destination open also takes nofollow: without it, an attacker who swaps the destination path to a symlink between the caller's check and the open redirects the O_TRUNC/O_CREAT to whatever file the symlink points at. Threading the same flag through safe_copy_file gives symmetric protection on both ends. Tests cover: open_source follows or ELOOPs based on the flag and accepts regular files either way; create_dest_restrictive sets 0o600 on new inodes, preserves existing inode modes, and rejects symlink swaps when nofollow is set (verifying the would-be victim is untouched); safe_copy_file end-to-end plus the nofollow-rejects- symlink cases for both source and destination. Module is gated behind a new uucore feature `safe-copy`, matching how `safe-traversal` and `fsxattr` are organized. Subsequent patches will rewire cp's platform helpers and mv's cross-device fallback to use these primitives, removing the duplication and giving mv O_NOFOLLOW for free.
Merging this PR will improve performance by 3.11%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Simulation | du_max_depth_balanced_tree[(6, 4, 10)] |
25.9 ms | 25.2 ms | +3.11% |
Comparing sylvestre:feat/safe-copy-foundation (b1096ce) with main (3057b7d)
Footnotes
-
46 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. ↩
sylvestre
added a commit
to sylvestre/coreutils
that referenced
this pull request
May 3, 2026
nonontb
pushed a commit
to nonontb/coreutils
that referenced
this pull request
May 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
to have a better way to fix the TOCTOU issues