mirror of
https://github.com/coder/coder.git
synced 2026-09-21 20:51:01 +08:00
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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user