diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-02-18 12:09:37 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-02-19 21:48:20 +0100 |
| commit | 2be2288ee256f3b84a7de15b82894097a08fd939 (patch) | |
| tree | ca3bb9ac9f9aba7897d71e735f6f4b0e55ad9711 | |
| parent | b99141b797e3b90e028f2020a5ef1b13fc97e31d (diff) | |
syz-fuzzer: don't break syscalls during minimization
If the original call was successful, keep it successful during minimization.
Successful calls are much more valuable.
| -rw-r--r-- | syz-fuzzer/proc.go | 25 | ||||
| -rw-r--r-- | syz-fuzzer/workqueue.go | 9 |
2 files changed, 23 insertions, 11 deletions
diff --git a/syz-fuzzer/proc.go b/syz-fuzzer/proc.go index 9f7eb6973..605febeb8 100644 --- a/syz-fuzzer/proc.go +++ b/syz-fuzzer/proc.go @@ -103,7 +103,7 @@ func (proc *Proc) triageInput(item *WorkTriage) { panic("should not be called when coverage is disabled") } - newSignal := proc.fuzzer.corpusSignalDiff(item.signal) + newSignal := proc.fuzzer.corpusSignalDiff(item.info.Signal) if len(newSignal) == 0 { return } @@ -151,6 +151,11 @@ func (proc *Proc) triageInput(item *WorkTriage) { continue // The call was not executed. } inf := info[call1] + if item.info.Errno == 0 && inf.Errno != 0 { + // Don't minimize calls from successful to unsuccessful. + // Successful calls are much more valuable. + return false + } signal := cover.Canonicalize(inf.Signal) if len(cover.Intersection(newSignal, signal)) == len(newSignal) { return true @@ -167,11 +172,11 @@ func (proc *Proc) triageInput(item *WorkTriage) { proc.fuzzer.sendInputToManager(RpcInput{ Call: call.CallName, Prog: data, - Signal: []uint32(cover.Canonicalize(item.signal)), + Signal: []uint32(cover.Canonicalize(item.info.Signal)), Cover: []uint32(inputCover), }) - proc.fuzzer.addInputToCorpus(item.p, item.signal, sig) + proc.fuzzer.addInputToCorpus(item.p, item.info.Signal, sig) if item.flags&ProgSmashed == 0 { proc.fuzzer.workQueue.enqueue(&WorkSmash{item.p, item.call}) @@ -228,11 +233,17 @@ func (proc *Proc) executeHintSeed(p *prog.Prog, call int) { func (proc *Proc) execute(execOpts *ipc.ExecOpts, p *prog.Prog, flags ProgTypes, stat Stat) []ipc.CallInfo { info := proc.executeRaw(execOpts, p, stat) for _, callIndex := range proc.fuzzer.checkNewSignal(info) { + info := info[callIndex] + // info.Signal points to the output shmem region, detach it before queueing. + info.Signal = append([]uint32{}, info.Signal...) + // None of the caller use Cover, so just nil it instead of detaching. + // Note: triage input uses executeRaw to get coverage. + info.Cover = nil proc.fuzzer.workQueue.enqueue(&WorkTriage{ - p: p.Clone(), - call: callIndex, - signal: append([]uint32{}, info[callIndex].Signal...), - flags: flags, + p: p.Clone(), + call: callIndex, + info: info, + flags: flags, }) } return info diff --git a/syz-fuzzer/workqueue.go b/syz-fuzzer/workqueue.go index 80905af26..62648336c 100644 --- a/syz-fuzzer/workqueue.go +++ b/syz-fuzzer/workqueue.go @@ -6,6 +6,7 @@ package main import ( "sync" + "github.com/google/syzkaller/pkg/ipc" "github.com/google/syzkaller/prog" ) @@ -38,10 +39,10 @@ const ( // During triage we understand if these programs in fact give new coverage, // and if yes, minimize them and add to corpus. type WorkTriage struct { - p *prog.Prog - call int - signal []uint32 - flags ProgTypes + p *prog.Prog + call int + info ipc.CallInfo + flags ProgTypes } // WorkCandidate are programs from hub. |
