aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-04-29 07:55:44 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-04-30 09:36:03 +0000
commit9232148686b36aed88151c1bf82b1a1294d76f37 (patch)
treecb2a32c0cb35877242a450326203c098fa0db6ea
parent9cce14289ad236f3533dc976312343f379116066 (diff)
syz-fuzzer: pass bug frames in connect result
Move bug frames from check result to connect result. This allows to create gate and start executing programs in the syz-fuzzer earlier (before check finished). This will be required for moving syscall/feature checks to the host.
-rw-r--r--pkg/rpctype/rpctype.go8
-rw-r--r--syz-fuzzer/fuzzer.go40
-rw-r--r--syz-manager/manager.go11
-rw-r--r--syz-manager/rpc.go11
4 files changed, 41 insertions, 29 deletions
diff --git a/pkg/rpctype/rpctype.go b/pkg/rpctype/rpctype.go
index fa728a494..d9119d24e 100644
--- a/pkg/rpctype/rpctype.go
+++ b/pkg/rpctype/rpctype.go
@@ -76,8 +76,10 @@ type ConnectArgs struct {
}
type ConnectRes struct {
- EnabledCalls []int
- AllSandboxes bool
+ EnabledCalls []int
+ MemoryLeakFrames []string
+ DataRaceFrames []string
+ AllSandboxes bool
// This is forwarded from CheckArgs, if checking was already done.
Features *host.Features
// Fuzzer reads these files inside of the VM and returns contents in CheckArgs.Files.
@@ -96,8 +98,6 @@ type CheckArgs struct {
}
type CheckRes struct {
- MemoryLeakFrames []string
- DataRaceFrames []string
CoverFilterBitmap []byte
}
diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go
index 6068f6b62..cdce3b21f 100644
--- a/syz-fuzzer/fuzzer.go
+++ b/syz-fuzzer/fuzzer.go
@@ -167,6 +167,28 @@ func main() {
}
checkReq = new(rpctype.CheckArgs)
}
+
+ for _, feat := range r.Features.Supported() {
+ log.Logf(0, "%v: %v", feat.Name, feat.Reason)
+ }
+
+ inputsCount := *flagProcs * 2
+ fuzzerTool := &FuzzerTool{
+ name: *flagName,
+ manager: manager,
+ timeouts: timeouts,
+
+ requests: make(chan rpctype.ExecutionRequest, inputsCount),
+ results: make(chan executionResult, inputsCount),
+ }
+ gateCb := fuzzerTool.useBugFrames(r.Features, r.MemoryLeakFrames, r.DataRaceFrames)
+ fuzzerTool.gate = ipc.NewGate(gateSize, gateCb)
+
+ log.Logf(0, "starting %v executor processes", *flagProcs)
+ for pid := 0; pid < *flagProcs; pid++ {
+ startProc(fuzzerTool, pid, config, *flagResetAccState)
+ }
+
checkReq.Name = *flagName
checkReq.Files = host.ReadFiles(r.ReadFiles)
checkReq.Globs = make(map[string][]string)
@@ -184,25 +206,11 @@ func main() {
if checkReq.Error != "" {
log.SyzFatalf("%v", checkReq.Error)
}
- for _, feat := range r.Features.Supported() {
- log.Logf(0, "%v: %v", feat.Name, feat.Reason)
- }
if *flagRunTest {
runTest(target, manager, *flagName, executor)
return
}
- inputsCount := *flagProcs * 2
- fuzzerTool := &FuzzerTool{
- name: *flagName,
- manager: manager,
- timeouts: timeouts,
-
- requests: make(chan rpctype.ExecutionRequest, inputsCount),
- results: make(chan executionResult, inputsCount),
- }
- gateCb := fuzzerTool.useBugFrames(r.Features, checkRes.MemoryLeakFrames, checkRes.DataRaceFrames)
- fuzzerTool.gate = ipc.NewGate(gateSize, gateCb)
if checkRes.CoverFilterBitmap != nil {
if err := osutil.WriteFile("syz-cover-bitmap", checkRes.CoverFilterBitmap); err != nil {
log.SyzFatalf("failed to write syz-cover-bitmap: %v", err)
@@ -210,10 +218,6 @@ func main() {
}
// Query enough inputs at the beginning.
fuzzerTool.exchangeDataCall(inputsCount, nil, 0)
- log.Logf(0, "starting %v executor processes", *flagProcs)
- for pid := 0; pid < *flagProcs; pid++ {
- startProc(fuzzerTool, pid, config, *flagResetAccState)
- }
go fuzzerTool.exchangeDataWorker()
fuzzerTool.exchangeDataWorker()
}
diff --git a/syz-manager/manager.go b/syz-manager/manager.go
index 6fe51d6e3..b25d938da 100644
--- a/syz-manager/manager.go
+++ b/syz-manager/manager.go
@@ -1330,10 +1330,9 @@ func (mgr *Manager) collectSyscallInfo() map[string]*corpus.CallCov {
return calls
}
-func (mgr *Manager) fuzzerConnect() (BugFrames, map[uint32]uint32, signal.Signal) {
+func (mgr *Manager) currentBugFrames() BugFrames {
mgr.mu.Lock()
defer mgr.mu.Unlock()
-
frames := BugFrames{
memoryLeaks: make([]string, 0, len(mgr.memoryLeakFrames)),
dataRaces: make([]string, 0, len(mgr.dataRaceFrames)),
@@ -1344,8 +1343,14 @@ func (mgr *Manager) fuzzerConnect() (BugFrames, map[uint32]uint32, signal.Signal
for frame := range mgr.dataRaceFrames {
frames.dataRaces = append(frames.dataRaces, frame)
}
+ return frames
+}
+
+func (mgr *Manager) fuzzerConnect() (map[uint32]uint32, signal.Signal) {
+ mgr.mu.Lock()
+ defer mgr.mu.Unlock()
maxSignal := mgr.fuzzer.Load().Cover.CopyMaxSignal()
- return frames, mgr.execCoverFilter, maxSignal
+ return mgr.execCoverFilter, maxSignal
}
func (mgr *Manager) machineChecked(features *host.Features, globFiles map[string][]string,
diff --git a/syz-manager/rpc.go b/syz-manager/rpc.go
index 96283ee20..5c22bdc0e 100644
--- a/syz-manager/rpc.go
+++ b/syz-manager/rpc.go
@@ -86,7 +86,8 @@ type BugFrames struct {
// RPCManagerView restricts interface between RPCServer and Manager.
type RPCManagerView interface {
- fuzzerConnect() (BugFrames, map[uint32]uint32, signal.Signal)
+ currentBugFrames() BugFrames
+ fuzzerConnect() (map[uint32]uint32, signal.Signal)
machineChecked(features *host.Features, globFiles map[string][]string,
enabledSyscalls map[*prog.Syscall]bool, modules []host.KernelModule)
getFuzzer() *fuzzer.Fuzzer
@@ -133,6 +134,10 @@ func (serv *RPCServer) Connect(a *rpctype.ConnectArgs, r *rpctype.ConnectRes) er
checkRevisions(a, serv.cfg.Target)
serv.statVMRestarts.Add(1)
+ bugFrames := serv.mgr.currentBugFrames()
+ r.MemoryLeakFrames = bugFrames.memoryLeaks
+ r.DataRaceFrames = bugFrames.dataRaces
+
serv.mu.Lock()
defer serv.mu.Unlock()
r.EnabledCalls = serv.cfg.Syscalls
@@ -185,7 +190,7 @@ func (serv *RPCServer) Check(a *rpctype.CheckArgs, r *rpctype.CheckRes) error {
serv.checkDone = true
}
- bugFrames, execCoverFilter, maxSignal := serv.mgr.fuzzerConnect()
+ execCoverFilter, maxSignal := serv.mgr.fuzzerConnect()
runner := serv.findRunner(a.Name)
if runner == nil {
@@ -202,8 +207,6 @@ func (serv *RPCServer) Check(a *rpctype.CheckArgs, r *rpctype.CheckRes) error {
runner.instModules = serv.canonicalModules.NewInstance(modules)
runner.newMaxSignal = maxSignal
- r.MemoryLeakFrames = bugFrames.memoryLeaks
- r.DataRaceFrames = bugFrames.dataRaces
instCoverFilter := runner.instModules.DecanonicalizeFilter(execCoverFilter)
r.CoverFilterBitmap = createCoverageBitmap(serv.cfg.SysTarget, instCoverFilter)
return nil