toolsrv: neutralize repo-controlled core.fsmonitor in tool env
GitSpawn class (Sep 2026): a repo's .git/config can set core.fsmonitor to a command that executes on any git index refresh, silently and as the user. Ollie never spawns git in its own plumbing (repo detection is os.Stat), but model-run git inside a malicious repo would fire it. - exec: force core.fsmonitor=false via GIT_CONFIG_* in sandboxed tool env - turn: wrap repo AGENTS.md in <context> markers (untrusted data, filtered by KDE chat rendering) - AGENTS.md: document the no-git-in-plumbing invariant (lesson 16)
This commit is contained in:
parent
989aa0400d
commit
3ca84487c5
|
|
@ -244,3 +244,5 @@ KDE integration is part of this repository under `kde/`. Build and install it th
|
|||
14. **Separate index files for separate concerns.** Don't cram session and agent data into one line. `session/idx` lists sessions; `session/{s}/agent/idx` lists agents per session. Simpler parsing, fewer race conditions, cleaner code.
|
||||
|
||||
15. **Split large files by concern, not by size.** A 900-line file with mixed responsibilities is worse than three 300-line files with clear boundaries. Name files by what they do (`dispatch.go`, `compact.go`, `retry.go`), not by their parent type (`agent_dispatch.go`).
|
||||
|
||||
16. **Never shell out to git in agent plumbing.** A repo's own `.git/config` can name commands (`core.fsmonitor`, hooks, filters) that run as the user on any git invocation — silently, before any prompt (GitSpawn class, Sep 2026). Repo detection stays `os.Stat(.git)` (`util/paths.go`, `cmd/toolsrv/internal/server/proc.go`). If a feature needs git context, run `git -c core.fsmonitor=false ...` inside the sandbox, or read the files directly. Sandboxed tool env already forces `core.fsmonitor=false` via `GIT_CONFIG_*` (cmd/toolsrv/internal/exec/exec.go).
|
||||
|
|
|
|||
|
|
@ -420,9 +420,12 @@ func (ag *Agent) autoWarnLimit(ctx context.Context) int {
|
|||
func (ag *Agent) spawnContext(ctx context.Context) string {
|
||||
var parts []string
|
||||
// Inject AGENTS.md from the working directory if it exists.
|
||||
// Repo-provided content is untrusted data: wrap it so consumers and the
|
||||
// model can distinguish it from user/system instructions (KDE filters
|
||||
// <context> blocks in chat rendering).
|
||||
if cwd := ag.Cwd(); cwd != "" {
|
||||
if data, err := os.ReadFile(cwd + "/AGENTS.md"); err == nil && len(data) > 0 {
|
||||
parts = append(parts, string(data))
|
||||
parts = append(parts, "<context>\n"+string(data)+"\n</context>")
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, "\n\n---\n\n")
|
||||
|
|
|
|||
|
|
@ -158,6 +158,13 @@ func executeSandboxed(ctx context.Context, toolPath, stdinData, cwd string, envE
|
|||
envMap["NAMESPACE"] = ns
|
||||
}
|
||||
}
|
||||
// Neutralize repo-controlled git config (GitSpawn / core.fsmonitor):
|
||||
// tools run with CWD inside a repository whose .git/config may name
|
||||
// commands (fsmonitor) that execute on any index refresh. GIT_CONFIG_*
|
||||
// acts like `-c core.fsmonitor=false` and overrides repo/global config.
|
||||
envMap["GIT_CONFIG_COUNT"] = "1"
|
||||
envMap["GIT_CONFIG_KEY_0"] = "core.fsmonitor"
|
||||
envMap["GIT_CONFIG_VALUE_0"] = "false"
|
||||
|
||||
var cmd *osExec.Cmd
|
||||
if yolo {
|
||||
|
|
|
|||
Loading…
Reference in New Issue