Repository navigation
fix(copy): reject raced symlink destinations and stop hooks on failure - #220
Conversation
|
No actionable comments were generated in the recent review. WalkthroughStaged file and directory publication now rejects destination symlinks that appear after copy checks. Copy failures propagate through ChangesWorktree copying
Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant cmd_create
participant cmd_pr
participant _post_create_copy
participant _copy_resolved_directories
participant hooks_and_tools
cmd_create->>_post_create_copy: copy configured files and directories
cmd_pr->>_post_create_copy: copy configured files and directories
_post_create_copy->>_copy_resolved_directories: copy resolved directories
_copy_resolved_directories-->>_post_create_copy: return copy status
_post_create_copy-->>cmd_create: return failure when copying fails
_post_create_copy-->>cmd_pr: return failure when copying fails
Note over cmd_create,hooks_and_tools: Commands stop before hooks and tools on copy failure
Possibly related PRs
Suggested reviewers: Merge Risk:
|
e0d8891 to
3724972
Compare
Description
When a destination symlink appears after directory-copy checks, plain
mvcan move the staged directory into the link's referent, leave the link in the worktree, and report success. An approvedpostCreatehook can then resolve its tool through that link.Use
mv -hon macOS andmv -Ton GNU platforms when publishing staged directories and leaves. Propagate directory-copy failures throughcopy,new, andpr; creation stops before hooks and automatic tool launches, leaving the worktree available for inspection. Add seven regression tests and document the writable-directory trust boundary.Motivation
Related: VULN-600.
A benign, deterministic fixture against
2d4852dinserted a symlink immediately before the native move. Before this change, an outside copy occurred, a redirected tool wrote a marker, and creation returned success. After this change, creation returns failure, no outside copy occurs, and the hook marker is absent. A normal-copy control still runs its copied tool exactly once.This overlaps the copy-confinement work in #208/#210. It does not establish a repository-identity or hook-approval bypass from #207.
Type of Change
Testing
After rebasing onto
801f33c(including #215 and #216), all 130 tests in the four affected BATS files passed under Bash 5. All 14 selected publication and trailing-slash regression checks passed under Bash 3.2. ShellCheck, completion checks, and diff checks also passed. The rebase retained both independently added tests at the conflict location.Initial full-suite validation on macOS with Bash 3.2.57 and Bash 5.3.20, before rebasing:
cmd_copyregression was covered by a subsequent 14/14 command-suite run.git diff --checkpass.Native Linux and Windows execution has not been tested locally; CI should validate the GNU path.
Scope and limitations
The fixture uses one UID and deliberately schedules the mutation. The reported cross-UID/setgid conditions and 7/60 success rate remain unverified; no severity or duplicate determination is implied.
This is focused hardening of destination publication and error handling. Sources, worktrees, and their ancestors must still be writable only by trusted users. Mutable ancestors, later changes to tools, and arbitrary concurrent writers remain outside an execution-isolation guarantee. Hook approval continues to cover command definitions rather than pinning delegated code.
No new dependency, command, flag, or configuration key is introduced. Failed creation leaves its worktree in place for inspection and cleanup.
License Acknowledgment
This contribution is submitted under the repository's Apache License 2.0.
Summary by CodeRabbit
Bug Fixes
git gtr newandgit gtr prbefore post-create hooks or automatic tool launches. The worktree remains in place, and the command reports failure.Documentation