fix(agent/agentproc): read process info before output to prevent TOCTOU (#25646)

handleProcessOutput read proc.output() then proc.info() using
separate locks. Between the two reads the exit goroutine could
finish I/O and set running=false, pairing stale output with final
status. On Windows CI this caused OutputExceedsBuffer to flake
when the buffer snapshot caught mid-write data (OmittedBytes=0)
but info reported the process as exited.

Swap the read order so info is read first. The exit goroutine
completes cmd.Wait (draining all pipe data) before setting
running=false, so seeing Running=false guarantees the subsequent
output read reflects the final buffer state.

Closes CODAGT-399
This commit is contained in:
Mathias Fredriksson
2026-05-25 17:27:29 +03:00
committed by GitHub
parent 12f082c864
commit c8359d8598
+6 -1
View File
@@ -200,8 +200,13 @@ func (api *API) handleProcessOutput(rw http.ResponseWriter, r *http.Request) {
// Fall through to read snapshot below.
}
output, truncated := proc.output()
// Read info before output to avoid a TOCTOU race. The exit
// goroutine completes all buffer writes (cmd.Wait) before
// setting running=false, so if info reports the process as
// exited, the subsequent output read is guaranteed to reflect
// the final buffer state.
info := proc.info()
output, truncated := proc.output()
httpapi.Write(ctx, rw, http.StatusOK, workspacesdk.ProcessOutputResponse{
Output: output,