Skip to content

Commit

Permalink
syz-fuzzer: don't reminimize all programs from corpus on start
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
dvyukov committed Jan 18, 2017
1 parent f03e9df commit ffe3274
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 32 deletions.
7 changes: 6 additions & 1 deletion rpctype/rpctype.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ type RpcInput struct {
Cover []uint32
}

type RpcCandidate struct {
Prog []byte
Minimized bool
}

type ConnectArgs struct {
Name string
}
Expand Down Expand Up @@ -39,7 +44,7 @@ type PollArgs struct {
}

type PollRes struct {
Candidates [][]byte
Candidates []RpcCandidate
NewInputs []RpcInput
}

Expand Down
70 changes: 42 additions & 28 deletions syz-fuzzer/fuzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -73,7 +79,7 @@ var (

triageMu sync.RWMutex
triage []Input
candidates []*prog.Prog
candidates []Candidate

gate *ipc.Gate

Expand Down Expand Up @@ -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()
Expand All @@ -215,18 +221,18 @@ 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))]
p := p0.Clone()
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)
}
}
}()
Expand Down Expand Up @@ -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)
}
Expand All @@ -287,7 +293,7 @@ func main() {
corpusMu.Unlock()
} else {
triageMu.Lock()
candidates = append(candidates, p)
candidates = append(candidates, Candidate{p, candidate.Minimized})
triageMu.Unlock()
}
}
Expand Down Expand Up @@ -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)
Expand All @@ -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()
Expand All @@ -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()
Expand Down
12 changes: 9 additions & 3 deletions syz-manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit ffe3274

Please sign in to comment.