Conversation
The sandbox package declares RunStatusTimeout and analysis.StatusForRunResult maps it to StatusErrorTimeout, but nothing ever assigns it, so a phase that hangs is reported as an ordinary analysis failure. Give each dynamic analysis phase a deadline, kept below the sandbox container's own 30 minute self-destruct timer, and classify the run result with the context in hand: a process killed by the deadline reaches cmd.Wait() as a plain *exec.ExitError, so the context has to be checked before the process error. Refs: ossf#142 Signed-off-by: Eljees <57435526+Eljees@users.noreply.github.com>
Eljees
force-pushed
the
fix/report-dynamic-analysis-timeout-142
branch
from
September 10, 2026 06:18
cea60b1 to
a2c947b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Addresses #142 — specifically the part @calebbrown described in the follow-up comment: "this does not give us any clear reporting on timeout as the cause of termination. We should record when a dynamic analysis run terminated due to a timeout."
The reporting chain for that already exists end to end, and only the source of the value is missing. On current
main:StatusForRunResultmapsRunStatusTimeouttoStatusErrorTimeout, andinternal/worker/logging.gologs that asAnalysis error - timeout. Nothing ever assignsRunStatusTimeout, so that branch is unreachable and a run that hangs is reported as an ordinary analysis error.Two changes:
1.
internal/worker/rundynamic.go— give each phase a deadline.runDynamicAnalysisPhasenow runs undercontext.WithTimeout(..., dynamicAnalysisPhaseTimeout). The value is 25 minutes, deliberately below the sandbox container's ownsleep 30mentrypoint (sandboxes/dynamicanalysis/Dockerfile), so the Go side observes the deadline rather than racing the container's forced shutdown.phaseCtxis the context already passed todynamicanalysis.Run→sb.Run, so the deadline reaches the sandbox command without any other plumbing.2.
internal/sandbox/sandbox.go— classify the result with the context in hand.The status logic moves out of
podmanSandbox.RunintoclassifyRunResult(ctx, err), which checksctx.Err() == context.DeadlineExceededbefore inspecting the process error. A process killed by the deadline surfaces tocmd.Wait()as a plain*exec.ExitError(signal: killed), indistinguishable from an ordinary non-zero exit, so the context has to be consulted first or the timeout is reported asRunStatusFailure. Success, ordinary failure and the unknown-error case behave exactly as before.Verification
Go 1.26.3, in a container, against
c5c4500.Control — pristine
mainwith only the new test file added:With the patch:
The timeout test does not fabricate the error: it runs
sleep 5under a 200 ms deadline and handscmd.Run()'s actual*exec.ExitErrorto the classifier, which is the case that used to be misread.go vet ./internal/sandbox/...andgofmt -lon the three touched files are both clean.Full suite, before and after.
go test ./internal/...fails in the same four packages on pristinemainand with the patch —pkgmanager(TestDownload, needs network),staticanalysis,staticanalysis/basicdataandstaticanalysis/parsing(all neednpm, which my container lacks). The only package whose result changes isinternal/sandbox, from[build failed]in the control took.What I could not run here:
go build ./...does not complete in my environment —google.golang.org/apifails to resolve through both the module proxy and direct mode from this network. That is unrelated to the diff (neither touched package imports it), but I would rather say so than imply a full build passed. CI will cover it.Open question
dynamicAnalysisPhaseTimeoutis a constant. If you would prefer it as a flag on the worker, or derived from the sandbox image's own timer rather than hard-coded alongside it, say the word and I will change it — I kept it constant to hold the diff to the reporting gap in the issue.AI-assisted: I used Claude to help locate the unreachable
RunStatusTimeoutbranch and to draft the patch and the tests. I reviewed every line, ran the control on pristinemainbefore the fix and the suite before and after, and the analysis and the runs are mine.