| id | 2606122012 |
|---|---|
| title | Add lstat guard to hook-file install, uninstall, and status |
| status | ✅ |
| summary | S001 from the 2026-06-12 git/LSP audit: ensurePreMergeCommitHook, runPreMergeCommitUninstall, and runPreMergeCommitStatus all read, write, or remove the hook path without a prior lstat check. WriteGitattributes already uses the correct pattern. Apply it here. |
| model | sonnet |
Close finding S001 from the 2026-06-12 git/LSP audit report.
Three functions read, write, or remove the hook path without a prior lstat check:
ensurePreMergeCommitHook(cmd/mdsmith/mergedriver.go:728):os.ReadFilethenos.WriteFilewith no guard. A symlink at.git/hooks/pre-merge-commitcauses both to follow it, writing to an arbitrary path outside the workspace.runPreMergeCommitUninstall(cmd/mdsmith/premergecommit.go:137):os.ReadFilethenos.Removewith no guard. A symlink causes Remove to delete an arbitrary file.runPreMergeCommitStatus(cmd/mdsmith/premergecommit.go:186):os.ReadFilewith no guard.
WriteGitattributes (internal/githooks/githooks.go:703) is the
reference: lstatFile → reject if not regular → atomic
temp-then-rename. The hook-file operations should match.
- Red: write a failing test for
ensurePreMergeCommitHookthat places a symlink at.git/hooks/pre-merge-commitand asserts the function returns an error instead of following the link. - Green: add an
os.Lstatguard inensurePreMergeCommitHookbeforeos.ReadFile. Replaceos.WriteFilewith an atomic temp-then-rename helper (writeHookFile) mirroringwriteGitattributesFile. - Red: write a failing test for
runPreMergeCommitUninstallthat places a symlink and assertsos.Removeis not called. - Green: add lstat guards in
runPreMergeCommitUninstallbeforeos.ReadFileand beforeos.Remove; reject if not regular. - Red/Green: add lstat guard to the
runPreMergeCommitStatusos.ReadFilecall; reject symlinks before reading. - Run
go test ./cmd/mdsmith/... ./internal/...; all pass. - Run
go run ./cmd/mdsmith check .; no regressions.
- A symlink at
.git/hooks/pre-merge-commitcausesmerge-driver install,pre-merge-commit install,pre-merge-commit uninstall, andpre-merge-commit statusto each return a clear error instead of following the link. - The fix uses the same pattern as
WriteGitattributes. - All existing tests pass.