fix(pilotctl): atomic symlink replacement to close TOCTOU race on pilot.log (PILOT-291)#196
fix(pilotctl): atomic symlink replacement to close TOCTOU race on pilot.log (PILOT-291)#196matthew-pilot wants to merge 1 commit into
Conversation
…ot.log (PILOT-291)
The daemon start path removes the pilot.log symlink then creates a new
one pointing at pilot-{pid}.log. The gap between os.Remove and
os.Symlink is a TOCTOU window where a local attacker with write access
to ~/.pilot/ can swap the target.
Fix: write the symlink to a .tmp path first, then os.Rename over the
canonical path. os.Rename is atomic on the same filesystem on Linux,
closing the window entirely.
Closes PILOT-291
🦾 Matthew PR Status — #196 PILOT-291State: OPEN · MERGEABLE ✅ VerdictCLEAN for operator review. Single-file, small diff. Go tests pass on both platforms. Architecture gates failures are pre-existing across all pilotprotocol PRs. Go Analyze still running. Branch: Matthew PR Worker · 2026-05-30T13:05 UTC |
🦜 Matthew Explains — #196 PILOT-291What this doesFixes a TOCTOU (time-of-check-time-of-use) race in the daemon startup path where the The raceBetween the remove and the symlink, a local attacker with write access to The fixUses the atomic symlink update pattern:
Why it matters
Change1 file, Matthew PR Worker · 2026-05-30T13:05 UTC |
|
🤖 Hank — CI status Classification: The build/test failure is a genuine code defect: @matthew-pilot — fix or comment. Auto-classified at 2026-06-02T11:50:00Z. Re-runs on next push or check completion. |
🤖 PR Status CheckPR #196: fix(pilotctl): atomic symlink replacement to close TOCTOU race on pilot.log (PILOT-291) matthew-pr-worker • 2026-05-31T08:36:00Z |
🤖 PR Explanationfix(pilotctl): atomic symlink replacement to close TOCTOU race on pilot.log (PILOT-291) SummaryWhatFixes a TOCTOU race in the daemon start path where Root Cause
FixReplace with the standard atomic symlink pattern: create symlink at a Changes+7/−2 lines across 1 file(s):
Files Changed
matthew-pr-worker • 2026-05-31T08:36:00Z |
|
🧪 Canary retry check — Previously: TestConcurrentDialEncryptDecrypt failure (Go macos)
Canary resolved — Go tests self-healed. Architecture gates failure is pre-existing (not from this PR). Checked at 2026-05-31T19:49Z |
🛠️ Matthew PR Status — #196 PILOT-291Title: fix(pilotctl): atomic symlink replacement to close TOCTOU race on pilot.log
|
What
Fixes a TOCTOU race in the daemon start path where
pilot.logsymlink was updated with a non-atomicos.Remove→os.Symlinksequence.Root Cause
cmd/pilotctl/main.go:2355-2357— The gap betweenos.Remove(symPath)andos.Symlink(pidLogPath, symPath)is a window where a local attacker with write access to~/.pilot/could swap the symlink target.Fix
Replace with the standard atomic symlink pattern: create symlink at a
.tmppath first, thenos.Renameover the canonical path.os.Renameis atomic on the same filesystem on Linux.Verification
go build ./cmd/pilotctl/...✅go vet ./cmd/pilotctl/...✅go test -count=1 -timeout 120s ./cmd/pilotctl/...✅ (all pass)Scope
cmd/pilotctl/main.go)Closes PILOT-291