Skip to content

fix(store): eliminate TOCTOU race in write_atomic#16

Merged
mark-pro merged 3 commits intooneirosoft:mainfrom
don-petry:fix/write-atomic-toctou
Mar 31, 2026
Merged

fix(store): eliminate TOCTOU race in write_atomic#16
mark-pro merged 3 commits intooneirosoft:mainfrom
don-petry:fix/write-atomic-toctou

Conversation

@don-petry
Copy link
Copy Markdown
Contributor

Summary

  • Fixes a TOCTOU (time-of-check-to-time-of-use) race condition in write_atomic where remove_file followed by rename could lose the state file on a crash between the two calls.
  • On Unix, rename(2) atomically overwrites the target, so the remove_file call was unnecessary and harmful. Now uses a single fs::rename call.
  • On Windows, rename cannot overwrite, so uses remove_file + rename with temp-file cleanup on error.
  • Adds unit tests for write_atomic and tempfile dev-dependency.

Addresses item 2 in #10.

Test plan

  • write_atomic_creates_new_file — writing to a non-existent path succeeds
  • write_atomic_overwrites_existing_file — overwriting produces correct content
  • write_atomic_creates_parent_dirs — nested parent directories are created

🤖 Generated with Claude Code

On Unix, fs::rename atomically overwrites the target, so the prior
remove_file call was unnecessary and introduced a window where a crash
between remove and rename would lose the state file entirely.

Split the implementation with cfg(unix) / cfg(windows):
- Unix: single rename call (fully atomic)
- Windows: remove then rename with temp-file cleanup on error

Also adds unit tests for write_atomic and tempfile dev-dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 31, 2026 02:17
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the store layer’s atomic write helper to avoid a Unix TOCTOU window by relying on rename(2) overwrite semantics, and introduces unit tests around write_atomic.

Changes:

  • Switch Unix implementation to a single fs::rename (atomic overwrite) instead of remove_file + rename.
  • Add a Windows-specific path that removes the destination before renaming and cleans up the temp file on rename error.
  • Add unit tests for write_atomic and add tempfile as a dev-dependency.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/core/store/fs.rs Adjusts write_atomic platform behavior and adds unit tests covering create/overwrite/parent-dir creation.
Cargo.toml Adds tempfile under [dev-dependencies] for the new tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Add fallback block for non-Unix/non-Windows targets
- Clean up temp file on rename error in Unix path
- Handle remove_file errors explicitly in Windows path (allow NotFound)
- Clarify comment wording about atomicity guarantees

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mark-pro mark-pro merged commit 92e3535 into oneirosoft:main Mar 31, 2026
1 check passed
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.

3 participants