proc: fuzz eval stack machine and harden call-injection paths - #4420
Open
derekparker wants to merge 9 commits into
Open
proc: fuzz eval stack machine and harden call-injection paths#4420derekparker wants to merge 9 commits into
derekparker wants to merge 9 commits into
Conversation
Improve FuzzEvalExpression with expression-string mutation and a shared internal-error helper. Add FuzzEvalStackOps (opcode programs) and FuzzCallInjectionProtocol (mock debugCall register sequences). Guard empty fncalls before CallInjectionSetTarget (go-delve#4085/go-delve#4363), bound evalStack.run against infinite JumpAlways cycles, and smoke the new fuzzers from the CI fuzz script.
Move the stack-depth validation used by Compile out of compileCtx so tests can call the same implementation. FuzzEvalStackOps primary mode now filters via evalop.DepthCheck instead of a parallel reimplementation.
Replace manual slice indexing with bytes.Reader and small read helpers so truncated fuzz inputs stay easy to follow.
Collapse Test*_Foo top-level tests into shared suites so related cases share structure and setup more cleanly.
Roll.depthCheck reported (1,1) but executeOp indexes N+1 stack slots, so the shared DepthCheck filter admitted programs that panicked. Align the check with the real access and drop decoder ops that fail as type mismatches rather than depth errors.
Move the two jump cases Compile never emits into TestDepthCheck and delete TestEvalStackOpsDepthOK, which only retested the one-line fuzz filter.
Drop the compileCtx.depthCheck trampoline; CompileAST and CompileSet already have the ops slice.
Drop export_test.go's trampoline; proc_test can use the capitalized helper from fuzz_helpers_test.go directly.
Make the opcode decoder total, skip Compile end-depth in the fuzz filter, and run 5s smokes only in fuzz mode so TeamCity seed stays a corpus check. Guard remaining empty-fncall peeks, bound JumpAlways cycles with a length-relative step limit, and gitignore setup dumps.
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.
Follow-up to #4412. Adds two in-process fuzzers for paths
FuzzEvalExpressionnever sees, and uses them to close real eval / call-injection bugs.
FuzzEvalStackOpsfeeds opcode programs toevalStack. The decoder istotal (
tag % N), jump targets are remapped to the actual program length,and the filter is
DepthCheck(ops, -1)(underflow / joins only — notCompile's end-depth 0/1, so
Rollactually runs).FuzzCallInjectionProtocoldrives realfuncCallStep/funcCallFinish/evalStack.runwith a mock protocol register, coveringpremature
RestoreRegisterswithout a livedebugCallV2target.FuzzEvalExpressiontakes a secondstringinput and seeds a sample ofreal and invalid expressions.
Production fixes found along the way:
Roll.depthChecknow reportsN+1slots, matchingexecuteOp.DepthCheckrejects out-of-range jump targets (used to indexdepth[]and panic) and swaps the end-depth error args.
fncallsis a clean"terminated before target"error(
requireFncall), not a panic inSetTarget/funcCallStep/ Complete(proc: telemetry report: index error in fncallPeek while resuming execution of a call injection #4085, telemetry report: pkg/proc: evalCallInjectionSetTarget missing an argument #4363).
evalStack.runboundsJumpAlwayscycles with a length-relative steplimit (
max(1024, len(ops)*256)). DepthCheck treats a self-jump as valid.5s smokes for the new fuzzers run in
_scripts/fuzz_eval_expression.sh fuzzonly (nightly workflow). TeamCity
seedmode is still setup + corpus check.FuzzEvalExpression setup dumps are gitignored.
[Disclaimer: fuzz tests added via AI assistance]