From 3c7bb2247f61c5218d4cd58a558dc2496fba53a4 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 2 May 2024 07:53:37 +0200 Subject: syz-fuzzer: don't expect that manager can provide exact number of requests Syscall checker and syz-runtest don't necessary have the requested number of requests, so don't expect that we will get the requested number. --- syz-fuzzer/fuzzer.go | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go index 9520fea84..08eac5b93 100644 --- a/syz-fuzzer/fuzzer.go +++ b/syz-fuzzer/fuzzer.go @@ -179,8 +179,8 @@ func main() { manager: manager, timeouts: timeouts, - requests: make(chan rpctype.ExecutionRequest, inputsCount), - results: make(chan executionResult, inputsCount), + requests: make(chan rpctype.ExecutionRequest, 2*inputsCount), + results: make(chan executionResult, 2*inputsCount), } gateCb := fuzzerTool.useBugFrames(r.Features, r.MemoryLeakFrames, r.DataRaceFrames) fuzzerTool.gate = ipc.NewGate(gateSize, gateCb) @@ -218,7 +218,7 @@ func main() { } } // Query enough inputs at the beginning. - fuzzerTool.exchangeDataCall(inputsCount, nil, 0) + fuzzerTool.exchangeDataCall(nil, 0) go fuzzerTool.exchangeDataWorker() fuzzerTool.exchangeDataWorker() } @@ -282,8 +282,8 @@ func (tool *FuzzerTool) startExecutingCall(progID int64, pid, try int) { }) } -func (tool *FuzzerTool) exchangeDataCall(needProgs int, results []rpctype.ExecutionResult, - latency time.Duration) time.Duration { +func (tool *FuzzerTool) exchangeDataCall(results []rpctype.ExecutionResult, latency time.Duration) time.Duration { + needProgs := max(0, cap(tool.requests)/2-len(tool.requests)) a := &rpctype.ExchangeInfoRequest{ Name: tool.name, NeedProgs: needProgs, @@ -297,10 +297,11 @@ func (tool *FuzzerTool) exchangeDataCall(needProgs int, results []rpctype.Execut log.SyzFatalf("Manager.ExchangeInfo call failed: %v", err) } latency = osutil.MonotonicNano() - start - if needProgs != len(r.Requests) { - log.SyzFatalf("manager returned wrong number of requests: %v/%v", needProgs, len(r.Requests)) - } tool.updateMaxSignal(r.NewMaxSignal, r.DropMaxSignal) + if len(r.Requests) == 0 { + // This is possible during initial checking stage, backoff a bit. + time.Sleep(100 * time.Millisecond) + } for _, req := range r.Requests { tool.requests <- req } @@ -309,8 +310,18 @@ func (tool *FuzzerTool) exchangeDataCall(needProgs int, results []rpctype.Execut func (tool *FuzzerTool) exchangeDataWorker() { var latency time.Duration - for result := range tool.results { - results := []rpctype.ExecutionResult{tool.convertExecutionResult(result)} + ticker := time.NewTicker(3 * time.Second * tool.timeouts.Scale).C + for { + var results []rpctype.ExecutionResult + select { + case res := <-tool.results: + results = append(results, tool.convertExecutionResult(res)) + case <-ticker: + // This is not expected to happen a lot, + // but this is required to resolve potential deadlock + // during initial checking stage when we may get + // no test requests from the host in some requests. + } // Grab other finished calls, just in case there are any. loop: for { @@ -322,7 +333,7 @@ func (tool *FuzzerTool) exchangeDataWorker() { } } // Replenish exactly the finished requests. - latency = tool.exchangeDataCall(len(results), results, latency) + latency = tool.exchangeDataCall(results, latency) } } -- cgit mrf-deployment