Skip to content

fix(core): prevent concurrent quarantine destination overwrites - #207

Merged
Muawiya-contact merged 9 commits into
mainfrom
codex/fix-quarantine-destination-collisions
Oct 3, 2026
Merged

Muawiya-contact merged 9 commits into
mainfrom
codex/fix-quarantine-destination-collisions

Conversation

@Muawiya-contact

@Muawiya-contact Muawiya-contact commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

Problem

Two quarantine requests can flatten different source paths to the same name in the same second. Previously, destination selection and movement happened before the manifest lock; rename or the copy fallback could overwrite the first file.

Closes #195

Changes

  • Hold the existing mutex through destination selection, movement, manifest append and rollback. Restore-from-manifest and purge already share this lock. Revalidate report metadata and scan authority after waiting for that lock, immediately before moving.
  • Reserve move destinations with a hard link followed by source removal, falling back to an exclusively created copy when linking is unavailable. Both paths refuse existing files and dangling symlinks.
  • Skip dangling links when choosing a filename. Keep incomplete Unix copies private, preserve source permissions, and refuse to dereference symlinks in the copy fallback.
  • Roll back the newly created destination if source removal fails. Preserve it if the source can no longer be verified, and report the retained path or cleanup failure.
  • Document the process-local guarantee and remaining crash-recovery boundary.

The fallback reserves its destination atomically:

let mut options = std::fs::OpenOptions::new();
options.write(true).create_new(true);

Validation

  • Core and CLI tests passed on Linux, Windows and macOS, including concurrent requests with a fixed timestamp and a start barrier, distinct preserved payloads, both manifest records, and successful restore of both originals.
  • Regression tests cover occupied destinations in both move paths, dangling symlinks, copy permissions and symlink-source rejection. Additional review regressions verify authority checks under the lock, destination rollback after a source-removal failure, and preservation of the last surviving copy if the source disappears.
  • The lock-placement and failed-removal regressions both failed on the initial PR code and pass with the corrections.
  • Rejected scan authority is checked before directory creation and again before moving. The desktop rejection test now passes on all three platforms, with a core regression covering both checks.
  • Clippy passed for core and CLI, all targets and all features, with warnings denied.
  • Rust formatting, changed-file spelling, changelog validation and whitespace checks passed.
  • The existing CLI Unix-socket test required execution outside the restricted sandbox; the complete rerun passed.

Limits

The mutex serializes one process, including time spent copying large files. Independent processes must not share a quarantine directory: destination creation refuses overwrites, but the manifest still lacks an OS-level lock. Link/unlink and copy/remove are not crash-atomic; journaling remains separate work under the recovery design. All Linux, Windows and macOS core/CLI and desktop CI jobs passed.

Nine focused commits; no dependency or manifest-format changes.

@Muawiya-contact Muawiya-contact left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

ok

@Muawiya-contact
Muawiya-contact merged commit b0cd81f into main Oct 3, 2026
14 checks passed
@Muawiya-contact
Muawiya-contact deleted the codex/fix-quarantine-destination-collisions branch October 3, 2026 04:30
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.

Reserve quarantine destinations before moving concurrently selected files

1 participant