diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2022-04-19 10:16:51 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2022-04-29 17:16:33 +0200 |
| commit | 33d1aba90b07c4319e1617be24f6f6dfd1b71d5e (patch) | |
| tree | 3c0269519b2f2dfc50476d065a43a82d0137c3f8 /vm | |
| parent | a04ae3093de7eebc147770fe38a5bda96b5c0634 (diff) | |
vm: support variable output buffer size
Also update syz-crush to save RawOutput instead of output from the
Report.
Diffstat (limited to 'vm')
| -rw-r--r-- | vm/vm.go | 78 | ||||
| -rw-r--r-- | vm/vm_test.go | 2 |
2 files changed, 51 insertions, 29 deletions
@@ -181,19 +181,51 @@ const ( // Returns a non-symbolized crash report, or nil if no error happens. func (inst *Instance) MonitorExecution(outc <-chan []byte, errc <-chan error, reporter *report.Reporter, exit ExitCondition) (rep *report.Report) { + return inst.MonitorExecutionRaw(outc, errc, reporter, exit, 0).Report +} + +type ExecutionResult struct { + Report *report.Report + RawOutput []byte +} + +func (inst *Instance) MonitorExecutionRaw(outc <-chan []byte, errc <-chan error, + reporter *report.Reporter, exit ExitCondition, beforeContextSize int) (res *ExecutionResult) { + if beforeContextSize == 0 { + beforeContextSize = beforeContextDefault + } mon := &monitor{ - inst: inst, - outc: outc, - errc: errc, - reporter: reporter, - exit: exit, + inst: inst, + outc: outc, + errc: errc, + reporter: reporter, + beforeContext: beforeContextSize, + exit: exit, } - lastExecuteTime := time.Now() - ticker := time.NewTicker(tickerPeriod * inst.timeouts.Scale) + return &ExecutionResult{ + Report: mon.monitorExecution(), + RawOutput: mon.output, + } +} + +type monitor struct { + inst *Instance + outc <-chan []byte + errc <-chan error + reporter *report.Reporter + exit ExitCondition + output []byte + beforeContext int + matchPos int +} + +func (mon *monitor) monitorExecution() *report.Report { + ticker := time.NewTicker(tickerPeriod * mon.inst.timeouts.Scale) defer ticker.Stop() + lastExecuteTime := time.Now() for { select { - case err := <-errc: + case err := <-mon.errc: switch err { case nil: // The program has exited without errors, @@ -217,9 +249,9 @@ func (inst *Instance) MonitorExecution(outc <-chan []byte, errc <-chan error, } return mon.extractError(crash) } - case out, ok := <-outc: + case out, ok := <-mon.outc: if !ok { - outc = nil + mon.outc = nil continue } lastPos := len(mon.output) @@ -228,12 +260,12 @@ func (inst *Instance) MonitorExecution(outc <-chan []byte, errc <-chan error, bytes.Contains(mon.output[lastPos:], executingProgram2) { lastExecuteTime = time.Now() } - if reporter.ContainsCrash(mon.output[mon.matchPos:]) { + if mon.reporter.ContainsCrash(mon.output[mon.matchPos:]) { return mon.extractError("unknown error") } - if len(mon.output) > 2*beforeContext { - copy(mon.output, mon.output[len(mon.output)-beforeContext:]) - mon.output = mon.output[:beforeContext] + if len(mon.output) > 2*mon.beforeContext { + copy(mon.output, mon.output[len(mon.output)-mon.beforeContext:]) + mon.output = mon.output[:mon.beforeContext] } // Find the starting position for crash matching on the next iteration. // We step back from the end of output by maxErrorLength to handle the case @@ -254,7 +286,7 @@ func (inst *Instance) MonitorExecution(outc <-chan []byte, errc <-chan error, case <-ticker.C: // Detect both "no output whatsoever" and "kernel episodically prints // something to console, but fuzzer is not actually executing programs". - if time.Since(lastExecuteTime) > inst.timeouts.NoOutput { + if time.Since(lastExecuteTime) > mon.inst.timeouts.NoOutput { return mon.extractError(noOutputCrash) } case <-Shutdown: @@ -263,16 +295,6 @@ func (inst *Instance) MonitorExecution(outc <-chan []byte, errc <-chan error, } } -type monitor struct { - inst *Instance - outc <-chan []byte - errc <-chan error - reporter *report.Reporter - exit ExitCondition - output []byte - matchPos int -} - func (mon *monitor) extractError(defaultError string) *report.Report { diagOutput, diagWait := []byte{}, false if defaultError != "" { @@ -316,7 +338,7 @@ func (mon *monitor) createReport(defaultError string) *report.Report { Suppressed: report.IsSuppressed(mon.reporter, mon.output), } } - start := rep.StartPos - beforeContext + start := rep.StartPos - mon.beforeContext if start < 0 { start = 0 } @@ -362,8 +384,8 @@ var ( executingProgram1 = []byte("executing program") // syz-fuzzer, syz-runner output executingProgram2 = []byte("executed programs:") // syz-execprog output - beforeContext = 1024 << 10 - afterContext = 128 << 10 + beforeContextDefault = 1024 << 10 + afterContext = 128 << 10 tickerPeriod = 10 * time.Second waitForOutputTimeout = 10 * time.Second diff --git a/vm/vm_test.go b/vm/vm_test.go index 83c3f51eb..2bcbbc1db 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -69,7 +69,7 @@ func (inst *testInstance) Close() { } func init() { - beforeContext = maxErrorLength + 100 + beforeContextDefault = maxErrorLength + 100 tickerPeriod = 1 * time.Second waitForOutputTimeout = 3 * time.Second |
