feat(fast_io): renameat sandbox helper (SEC-1.j)#4693
Merged
Conversation
Closes the last TOCTOU window for path-based file renames in the receiver commit path by routing temp-file -> final-name and backup renames through `renameat(dirfd, leaf, dirfd, leaf)` when both endpoints sit beneath the destination sandbox root as single-component leaves. The helper lives in a new `at_syscalls_rename.rs` module rather than extending `at_syscalls.rs` so it can land alongside the in-flight SEC-1.i metadata helpers without textual conflict; the three modules can be re-folded once both PRs merge. - `renameat(old_dirfd, old_name, new_dirfd, new_name, replace)` raw helper. On Linux 3.15+ `replace=false` upgrades to `renameat2(RENAME_NOREPLACE)` and falls back to plain renameat on older kernels (ENOSYS / EINVAL / EOPNOTSUPP). - `renameat_via_sandbox_or_fallback(sandbox, old_dest, old_rel, old_path, new_dest, new_rel, new_path, replace)` adaptor that takes the sandbox fast path when both relatives are single components and the joined paths match; falls back to `std::fs::rename` otherwise. - Receiver wired at the two synchronous commit sites in `transfer::receiver::transfer::sync`: backup rename and the temp-file -> final-name rename. The io_uring fast path is preserved; sandbox routing applies to the synchronous fallback. Windows keeps the existing `std::fs::rename` path; the SEC-1.l audit confirmed NTFS handle-based APIs sidestep path TOCTOU naturally.
The Linux-only RENAME_NOREPLACE arm uses 'replace' for the renameat2 SYS_renameat2 dispatch. On macOS / non-Linux the parameter is unused because renameat(2) lacks the flag knob. Gate the unused-variable allow per-target.
1a699c7 to
7624f3d
Compare
4 tasks
oferchen
added a commit
that referenced
this pull request
May 21, 2026
…ship (#4695) Captures the hygiene follow-up to consolidate `crates/fast_io/src/dir_sandbox/at_syscalls{,_metadata,_rename}.rs` into a single `at_syscalls` namespace now that all three SEC-1 *at* helper PRs (.h #4683, .i #4690, .j #4693) are on master. Both .i and .j module headers explicitly scheduled the re-fold; this doc turns that into a concrete plan with section dividers, re-export collapse steps, and an LoC sanity check that confirms the consolidated file remains within the post-2026-05-18 LoC policy.
This was referenced May 21, 2026
Open
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.
Summary
renameat(dirfd, leaf, dirfd, leaf)when both endpoints sit as single-component leaves beneath the destination sandbox root.crates/fast_io/src/dir_sandbox/at_syscalls_rename.rsexposes a rawrenameat(old_dirfd, old_name, new_dirfd, new_name, replace)helper plus arenameat_via_sandbox_or_fallbackadaptor that mirrors the SEC-1.f/g/h/i shape. On Linux 3.15+,replace=falseupgrades torenameat2(RENAME_NOREPLACE)and falls back to plainrenameat(2)on older kernels (ENOSYS / EINVAL / EOPNOTSUPP), matching the upstreamutil1.cbackstop trade-off.transfer::receiver::transfer::sync: backup rename and temp-file -> final-name rename. io_uringIORING_OP_RENAMEATfast path is preserved; sandbox routing applies to the synchronous fallback. Windows keepsstd::fs::renameper the SEC-1.l NTFS-handle audit.RENAME_NOREPLACErefuses existing destination on Linux, and the common receiver temp-commit shape.Coordination with SEC-1.i (#4690)
at_syscalls_rename.rs) so the two PRs do not clash at any helper call site. They only touch the same lines at the re-export sites indir_sandbox/mod.rsandcrates/fast_io/src/lib.rs.Test plan
cargo nextest run -p fast_io --all-features -E 'test(at_syscalls_rename) + test(renameat)'cargo nextest run -p transfer --all-features -E 'test(sync) + test(receiver)'