aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-01-18 16:10:34 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-01-18 19:58:12 +0100
commitffe327412b008a8673e41cd6cbf08f3e98a14af9 (patch)
tree17c752e181bb50376a939bb3ea6f867acbe5a85f
parentf03e9df1b620f6ca029ed9cac7b3192d9d09268a (diff)
syz-fuzzer: don't reminimize all programs from corpus on start
Minimization takes considerable time on start, but the programs were already minimized. There are some chances that we could minimize it better this time, but still it does not worth very slow start (which is especially painful for development).
-rw-r--r--rpctype/rpctype.go7
-rw-r--r--syz-fuzzer/fuzzer.go70
-rw-r--r--syz-manager/manager.go12
3 files changed, 57 insertions, 32 deletions
diff --git a/rpctype/rpctype.go b/rpctype/rpctype.go
index 31e36fbfb..f64e90f4f 100644
--- a/rpctype/rpctype.go
+++ b/rpctype/rpctype.go
@@ -12,6 +12,11 @@ type RpcInput struct {
Cover []uint32
}
+type RpcCandidate struct {
+ Prog []byte
+ Minimized bool
+}
+
type ConnectArgs struct {
Name string
}
@@ -39,7 +44,7 @@ type PollArgs struct {
}
type PollRes struct {
- Candidates [][]byte
+ Candidates []RpcCandidate
NewInputs []RpcInput
}
diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go
index ae9b05c12..814986316 100644
--- a/syz-fuzzer/fuzzer.go
+++ b/syz-fuzzer/fuzzer.go
@@ -54,9 +54,15 @@ func hash(data []byte) Sig {
}
type Input struct {
- p *prog.Prog
- call int
- cover cover.Cover
+ p *prog.Prog
+ call int
+ cover cover.Cover
+ minimized bool
+}
+
+type Candidate struct {
+ p *prog.Prog
+ minimized bool
}
var (
@@ -73,7 +79,7 @@ var (
triageMu sync.RWMutex
triage []Input
- candidates []*prog.Prog
+ candidates []Candidate
gate *ipc.Gate
@@ -197,10 +203,10 @@ func main() {
continue
} else if len(candidates) != 0 {
last := len(candidates) - 1
- p := candidates[last]
+ candidate := candidates[last]
candidates = candidates[:last]
triageMu.Unlock()
- execute(pid, env, p, &statExecCandidate)
+ execute(pid, env, candidate.p, candidate.minimized, &statExecCandidate)
continue
} else {
triageMu.Unlock()
@@ -215,10 +221,10 @@ func main() {
corpusMu.RUnlock()
p := prog.Generate(rnd, programLength, ct)
Logf(1, "#%v: generated: %s", i, p)
- execute(pid, env, p, &statExecGen)
+ execute(pid, env, p, false, &statExecGen)
p.Mutate(rnd, programLength, ct, nil)
Logf(1, "#%v: mutated: %s", i, p)
- execute(pid, env, p, &statExecFuzz)
+ execute(pid, env, p, false, &statExecFuzz)
} else {
// Mutate an existing prog.
p0 := corpus[rnd.Intn(len(corpus))]
@@ -226,7 +232,7 @@ func main() {
p.Mutate(rs, programLength, ct, corpus)
corpusMu.RUnlock()
Logf(1, "#%v: mutated: %s <- %s", i, p, p0)
- execute(pid, env, p, &statExecFuzz)
+ execute(pid, env, p, false, &statExecFuzz)
}
}
}()
@@ -276,8 +282,8 @@ func main() {
for _, inp := range r.NewInputs {
addInput(inp)
}
- for _, data := range r.Candidates {
- p, err := prog.Deserialize(data)
+ for _, candidate := range r.Candidates {
+ p, err := prog.Deserialize(candidate.Prog)
if err != nil {
panic(err)
}
@@ -287,7 +293,7 @@ func main() {
corpusMu.Unlock()
} else {
triageMu.Lock()
- candidates = append(candidates, p)
+ candidates = append(candidates, Candidate{p, candidate.Minimized})
triageMu.Unlock()
}
}
@@ -427,21 +433,24 @@ func triageInput(pid int, env *ipc.Env, inp Input) {
if len(newCover) == 0 {
return
}
- inp.p, inp.call = prog.Minimize(inp.p, inp.call, func(p1 *prog.Prog, call1 int) bool {
- allCover := execute1(pid, env, p1, &statExecMinimize)
- coverMu.RLock()
- defer coverMu.RUnlock()
- if len(allCover[call1]) == 0 {
- return false // The call was not executed.
- }
- cov := allCover[call1]
- if len(cover.Intersection(newCover, cov)) != len(newCover) {
- return false
- }
- minCover = cover.Intersection(minCover, cov)
- return true
- }, false)
+ if !inp.minimized {
+ inp.p, inp.call = prog.Minimize(inp.p, inp.call, func(p1 *prog.Prog, call1 int) bool {
+ allCover := execute1(pid, env, p1, &statExecMinimize)
+ coverMu.RLock()
+ defer coverMu.RUnlock()
+
+ if len(allCover[call1]) == 0 {
+ return false // The call was not executed.
+ }
+ cov := allCover[call1]
+ if len(cover.Intersection(newCover, cov)) != len(newCover) {
+ return false
+ }
+ minCover = cover.Intersection(minCover, cov)
+ return true
+ }, false)
+ }
inp.cover = minCover
atomic.AddUint64(&statNewInput, 1)
@@ -462,7 +471,7 @@ func triageInput(pid int, env *ipc.Env, inp Input) {
corpusHashes[hash(data)] = struct{}{}
}
-func execute(pid int, env *ipc.Env, p *prog.Prog, stat *uint64) {
+func execute(pid int, env *ipc.Env, p *prog.Prog, minimized bool, stat *uint64) {
allCover := execute1(pid, env, p, stat)
coverMu.RLock()
defer coverMu.RUnlock()
@@ -480,7 +489,12 @@ func execute(pid int, env *ipc.Env, p *prog.Prog, stat *uint64) {
coverMu.Unlock()
coverMu.RLock()
- inp := Input{p.Clone(), i, cover.Copy(cov)}
+ inp := Input{
+ p: p.Clone(),
+ call: i,
+ cover: cover.Copy(cov),
+ minimized: minimized,
+ }
triageMu.Lock()
triage = append(triage, inp)
triageMu.Unlock()
diff --git a/syz-manager/manager.go b/syz-manager/manager.go
index 9a4d4af8d..93f0e87d0 100644
--- a/syz-manager/manager.go
+++ b/syz-manager/manager.go
@@ -58,7 +58,7 @@ type Manager struct {
enabledSyscalls string
enabledCalls []string // as determined by fuzzer
- candidates [][]byte // untriaged inputs
+ candidates []RpcCandidate // untriaged inputs
disabledHashes []string
corpus []RpcInput
corpusCover []cover.Cover
@@ -158,7 +158,10 @@ func RunManager(cfg *config.Config, syscalls map[int]bool) {
mgr.disabledHashes = append(mgr.disabledHashes, sig.String())
continue
}
- mgr.candidates = append(mgr.candidates, rec.Val)
+ mgr.candidates = append(mgr.candidates, RpcCandidate{
+ Prog: rec.Val,
+ Minimized: true, // don't reminimize programs from corpus, it takes lots of time on start
+ })
}
mgr.fresh = len(mgr.corpusDB.Records) == 0
Logf(0, "loaded %v programs (%v total)", len(mgr.candidates), len(mgr.corpusDB.Records))
@@ -743,7 +746,10 @@ func (mgr *Manager) hubSync() {
dropped++
continue
}
- mgr.candidates = append(mgr.candidates, inp)
+ mgr.candidates = append(mgr.candidates, RpcCandidate{
+ Prog: inp,
+ Minimized: false, // don't trust programs from hub
+ })
}
mgr.stats["hub add"] += uint64(len(a.Add))
mgr.stats["hub del"] += uint64(len(a.Del))