Skip to content

Make symlink preflight consistent for external and dangling targets #4829

Description

@Widthdom

Summary

With external-symlink following enabled, dry-run ignores an external link while execution later exits partial with “source changed after preflight” even though the target is static. Dangling symlinks also change severity between dry-run and execution (error versus warning).

Audit IDs: O-19 and O-33. Reproduced on current v1.40.3. Closed #4352 and #3515 are adjacent symlink-policy work, but neither covers this current preflight/execution disagreement.

Expected behavior

Dry-run and execution must classify the same resolved link target, apply the same follow policy, and report the same severity. A stable allowed target must not be misdiagnosed as a source-change race.

PR scope

Keep this to shared symlink discovery/preflight identity and severity. Do not broaden it into general filesystem traversal redesign.

Implementation guide for Codex 5.6 sol xhigh

  • Reproduce in isolated workspaces with internal, external, dangling, retargeted, directory, and file links.
  • Carry one canonical link identity and follow-policy decision from discovery through indexing instead of comparing incompatible link/target metadata.
  • Preserve real TOCTOU protection: a genuinely retargeted link between preflight and read must still be rejected safely.
  • Normalize dry-run/execution diagnostics and JSON categories.
  • Add Linux/macOS coverage and Windows capability-aware tests; do not assume symlink creation privileges.
  • Run full tests and add docs/changelog where behavior is user-visible.

Acceptance criteria

  • A static permitted external target indexes successfully.
  • Dry-run predicts the same inclusion and severity as execution.
  • Dangling targets have one documented severity/exit contract.
  • Real retargeting or escape outside policy is still detected and refused.

Metadata

Metadata

Assignees

No one assigned

    Labels

    .NETPull requests that update .NET codebugSomething isn't workingsecurity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions