Skip to content

fix: harden cache migration symlink checks#232

Merged
inureyes merged 1 commit into
mainfrom
fix/issue-229-pr-230-hardening
May 24, 2026
Merged

fix: harden cache migration symlink checks#232
inureyes merged 1 commit into
mainfrom
fix/issue-229-pr-230-hardening

Conversation

@inureyes

Copy link
Copy Markdown
Member

Summary

Follow-up hardening for merged PR #230. The cache migration now refuses a symlinked legacy cache root before composing records / energy-wal.bin child paths, and it treats any destination filesystem entry, including a dangling symlink, as occupied so the no-overwrite migration invariant holds.

Target PR reviewed

Linked Original Issues Reviewed

Review Findings

  • The merged migration helper checked symlinks at ~/.cache/all-smi/records and ~/.cache/all-smi/energy-wal.bin, but not at the legacy root ~/.cache/all-smi itself. A symlinked legacy root could therefore be followed while resolving child migration targets, which conflicts with the threat model documented in PR feat: unify cache paths via platform-aware dirs::cache_dir() (#229) #230 and the users-CSV cache-dir symlink refusal.
  • The destination guard used Path::exists(), which treats a dangling destination symlink as absent. That does not redirect writes, but it weakens the stated "never overwrite destination" invariant because an existing filesystem entry could be replaced.

Correctness Fixes

  • Split the root migration into migrate_legacy_cache_root(old_root, new_root) so tests can exercise the root-level decision without mutating process-global home/cache state.
  • Use symlink_metadata() on the legacy root and return before create_dir_all(new_root) or target joins when the root is a symlink or cannot be inspected.
  • Use symlink_metadata() for destination occupancy so files, directories, symlinks, and dangling symlinks all preserve the existing destination and skip migration.

Security Fixes

  • Root-level symlink refusal now matches the existing writer-side and users-CSV hardening rationale: a pre-planted ~/.cache/all-smi symlink is skipped rather than followed into attacker-controlled paths.
  • Added Unix regression coverage proving the migration does not create the new cache root or move data when the legacy root is a symlink.

Performance And Reliability

  • The change adds only one metadata lookup on startup when the legacy and platform cache roots differ. The migration remains best-effort, non-blocking on inspection errors, and still avoids copy/delete fallback across filesystems.
  • Added coverage for dangling destination symlinks to preserve the no-overwrite invariant under edge-case filesystem states.

Validation

  • env -u NO_COLOR RUSTFLAGS="-L /tmp/drmlinks" cargo test --bin all-smi cache_migration::tests:: -> passed, 7 tests.
  • env -u NO_COLOR RUSTFLAGS="-L /tmp/drmlinks" cargo test --bin all-smi -> passed, 1174 passed, 1 ignored.
  • env -u NO_COLOR RUSTFLAGS="-L /tmp/drmlinks" cargo test --test config_file_integration_test -> passed, 15 tests.
  • RUSTFLAGS="-L /tmp/drmlinks" cargo clippy --bin all-smi --tests -- -D warnings -> passed.
  • cargo fmt --check -> passed.
  • Note: the same binary unit suite fails under this local shell's ambient NO_COLOR=1 because ui::renderers::memory_renderer::tests::test_swap_row_active_uses_red_color intentionally asserts emitted red SGR; unsetting NO_COLOR matches CI behavior and passes.

Refs #229
Refs #230

Refuse a symlinked legacy cache root before composing migration targets, and treat any destination filesystem entry, including a dangling symlink, as occupied so the best-effort migration preserves the no-overwrite invariant.

Refs #229

Refs #230
@inureyes inureyes self-assigned this May 24, 2026
@inureyes inureyes added status:review Under review priority:medium Medium priority issue type:performance Performance improvements type:optimization Code optimization and efficiency improvements mode:local Local mode related labels May 24, 2026
@inureyes inureyes merged commit 0a1f420 into main May 24, 2026
3 of 4 checks passed
@inureyes inureyes deleted the fix/issue-229-pr-230-hardening branch May 24, 2026 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mode:local Local mode related priority:medium Medium priority issue status:review Under review type:optimization Code optimization and efficiency improvements type:performance Performance improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant