Skip to content

fix: implement recovery safety guardrails and collision-safe atomic output - #2

Merged
daniyusk merged 6 commits into
mainfrom
fix/recovery-safety-guardrails
Aug 27, 2026
Merged

daniyusk merged 6 commits into
mainfrom
fix/recovery-safety-guardrails

Conversation

@daniyusk

Copy link
Copy Markdown
Owner

Summary

This pull request implements safety protections to prevent JustGiveMyDisk from directly or indirectly modifying the source storage medium being recovered, and introduces a collision-safe, atomic file output policy.

Changes

1. Centralized Path Validation (CLI and TUI)

  • Added path_safety::Source to enforce read-only descriptor opening (O_RDONLY), verify fstat integrity against TOCTOU issues, and identify block devices.
  • Added validate_database_path and validate_destination_path to:
    • Reject SQLite databases or destinations matching the source device (detecting aliases, symlinks, and equivalent paths).
    • Reject database or destination paths situated on filesystems mounted from the recovery source (via /sys/dev/block inspection).
    • Reject destinations that are regular files or block devices.
    • Return canonicalized paths for downstream consumption.
  • Integrated path validation across both CLI commands (scan, recover) and the TUI.

2. Collision-Safe Atomic Recovery Output

  • Added recovery_output::sanitize_name to replace path delimiters, control characters, and reserved names with underscores.
  • Added recovery_output::CollisionTracker to detect case-insensitive filename collisions post-sanitization prior to file creation (including during --dry-run).
  • Added recovery_output::AtomicFile:
    • Enforces .partial staging files with O_EXCL and 0600 permissions.
    • Automatically cleans up partial files upon interruption or failure via RAII.
    • Atomically renames to the final destination upon successful completion (SYS_renameat2 with RENAME_NOREPLACE or atomic link/unlink).
    • Skips existing files by default without overwriting.
    • Detects and preserves stale partial files from previous interrupted runs.
    • Added explicit --overwrite flag to replace existing regular files and clear stale partial files.
    • Rejects overwriting symlinks or non-regular files even when overwrite is enabled.
  • Added ensure_safe_directory to traverse destination paths component by component and reject intermediate symlinks.

3. Testing and Build

  • Added unit tests: path_safety_unit and recovery_output_unit.
  • Added integration tests: path_safety_cli_integration and recovery_output_cli_integration.
  • Updated documentation in README.md.

@daniyusk
daniyusk marked this pull request as ready for review August 27, 2026 08:06
@daniyusk
daniyusk merged commit 7dfa0b5 into main Aug 27, 2026
6 checks 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.

1 participant