aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-05-02 07:53:37 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-05-02 16:24:59 +0000
commit3c7bb2247f61c5218d4cd58a558dc2496fba53a4 (patch)
tree0f308d862c55eae4dbe94ddd7e4f079bb9f34901
parentcf02e61c441d38e1eea04df5168aab7aee13f88f (diff)
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.
-rw-r--r--syz-fuzzer/fuzzer.go33
1 files 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)
}
}