diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2024-05-13 16:30:18 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-05-13 15:11:42 +0000 |
| commit | 4a623fface69b3124c66c6b0859ab1fc08b47e47 (patch) | |
| tree | c0c3d94ed4accf0b5dd883a176d72d5ada39d2f0 | |
| parent | 9026e14289eaf45a00ddddb8730f2092b956d99a (diff) | |
syz-manager: fix a race in logProgram()
logProgram() may race with Request.Done(), in which case the request
producer (fuzzer.Fuzzer) may well have already mutated a previously
executed prog.Prog instance.
| -rw-r--r-- | syz-manager/rpc.go | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/syz-manager/rpc.go b/syz-manager/rpc.go index 7323d5e38..ef4b81361 100644 --- a/syz-manager/rpc.go +++ b/syz-manager/rpc.go @@ -86,9 +86,10 @@ type Runner struct { } type Request struct { - req *fuzzer.Request - try int - procID int + req *fuzzer.Request + serialized []byte + try int + procID int } type BugFrames struct { @@ -316,7 +317,7 @@ func (serv *RPCServer) StartExecuting(a *rpctype.ExecutingRequest, r *int) error } runner.requests[a.ID] = req runner.mu.Unlock() - runner.logProgram(a.ProcID, req.req.Prog) + runner.logProgram(a.ProcID, req.serialized) return nil } @@ -529,7 +530,7 @@ func (serv *RPCServer) doneRequest(runner *Runner, resp rpctype.ExecutionResult, // RPC handlers are invoked in separate goroutines, so log the program here // if completion notification outrun start executing notification. if req.try < resp.Try { - runner.logProgram(resp.ProcID, req.req.Prog) + runner.logProgram(resp.ProcID, req.serialized) } if !serv.cfg.Cover { addFallbackSignal(req.req.Prog, info) @@ -550,6 +551,9 @@ func (serv *RPCServer) newRequest(runner *Runner, req *fuzzer.Request) (rpctype. return rpctype.ExecutionRequest{}, false } + // logProgram() may race with Done(), so let's serialize the program right now. + serialized := req.Prog.Serialize() + var signalFilter signal.Signal if req.SignalFilter != nil { newRawSignal := runner.instModules.Decanonicalize(req.SignalFilter.ToRaw()) @@ -561,8 +565,9 @@ func (serv *RPCServer) newRequest(runner *Runner, req *fuzzer.Request) (rpctype. id := runner.nextRequestID if runner.requests != nil { runner.requests[id] = Request{ - req: req, - try: -1, + req: req, + try: -1, + serialized: serialized, } } runner.mu.Unlock() @@ -616,9 +621,9 @@ func (serv *RPCServer) createExecOpts(req *fuzzer.Request) ipc.ExecOpts { } } -func (runner *Runner) logProgram(procID int, p *prog.Prog) { +func (runner *Runner) logProgram(procID int, serialized []byte) { buf := new(bytes.Buffer) - fmt.Fprintf(buf, "executing program %v:\n%s\n", procID, p.Serialize()) + fmt.Fprintf(buf, "executing program %v:\n%s\n", procID, serialized) select { case runner.injectLog <- buf.Bytes(): case <-runner.injectStop: |
