Skip to content

feat(fast_io): renameat sandbox helper (SEC-1.j)#4693

Merged
oferchen merged 2 commits into
masterfrom
feat/fast-io-renameat-sec1j
May 21, 2026
Merged

feat(fast_io): renameat sandbox helper (SEC-1.j)#4693
oferchen merged 2 commits into
masterfrom
feat/fast-io-renameat-sec1j

Conversation

@oferchen
Copy link
Copy Markdown
Owner

Summary

  • Closes the last TOCTOU window in the SEC-1 CVE-2026-29518 + CVE-2026-43619 mitigation chain by routing receiver-side temp-file -> final-name and backup renames through renameat(dirfd, leaf, dirfd, leaf) when both endpoints sit as single-component leaves beneath the destination sandbox root.
  • New crates/fast_io/src/dir_sandbox/at_syscalls_rename.rs exposes a raw renameat(old_dirfd, old_name, new_dirfd, new_name, replace) helper plus a renameat_via_sandbox_or_fallback adaptor that mirrors the SEC-1.f/g/h/i shape. On Linux 3.15+, replace=false upgrades to renameat2(RENAME_NOREPLACE) and falls back to plain renameat(2) on older kernels (ENOSYS / EINVAL / EOPNOTSUPP), matching the upstream util1.c backstop trade-off.
  • Receiver wired at the two synchronous commit sites in transfer::receiver::transfer::sync: backup rename and temp-file -> final-name rename. io_uring IORING_OP_RENAMEAT fast path is preserved; sandbox routing applies to the synchronous fallback. Windows keeps std::fs::rename per the SEC-1.l NTFS-handle audit.
  • 10 unit tests cover: raw renameat in same dir, ENOENT on missing source, AT_FDCWD interop, cross-dir rename via two distinct dirfds, sandbox fast path on single-component, sandbox fallback for multi-component source, sandbox fallback when sandbox absent, sandbox fallback when paths cross sandbox boundary, default-overwrite semantics, RENAME_NOREPLACE refuses existing destination on Linux, and the common receiver temp-commit shape.

Coordination with SEC-1.i (#4690)

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)'
  • Full CI matrix (fmt+clippy, nextest stable, Windows, macOS, Linux musl) green.
  • Interop suite green (CI workflow "Interop Validation") - exercises the receiver commit path through real upstream rsync sender.

@github-actions github-actions Bot added the enhancement New feature or request label May 21, 2026
oferchen added 2 commits May 21, 2026 23:35
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.
@oferchen oferchen force-pushed the feat/fast-io-renameat-sec1j branch from 1a699c7 to 7624f3d Compare May 21, 2026 20:35
@oferchen oferchen merged commit 95a62dd into master May 21, 2026
55 checks passed
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant