func execute(pid int, env *ipc.Env, p *prog.Prog, stat *uint64) { allCover := execute1(pid, env, p, stat) coverMu.RLock() defer coverMu.RUnlock() for i, cov := range allCover { if len(cov) == 0 { continue } c := p.Calls[i].Meta diff := cover.Difference(cov, maxCover[c.CallID]) diff = cover.Difference(diff, flakes) if len(diff) != 0 { coverMu.RUnlock() coverMu.Lock() maxCover[c.CallID] = cover.Union(maxCover[c.CallID], diff) coverMu.Unlock() coverMu.RLock() inp := Input{p.Clone(), i, cover.Copy(cov)} triageMu.Lock() triage = append(triage, inp) triageMu.Unlock() } } }
func addInput(inp RpcInput) { p, err := prog.Deserialize(inp.Prog) if err != nil { panic(err) } if inp.CallIndex < 0 || inp.CallIndex >= len(p.Calls) { panic("bad call index") } call := p.Calls[inp.CallIndex].Meta sig := hash(inp.Prog) if _, ok := corpusHashes[sig]; ok { return } cov := cover.Canonicalize(inp.Cover) diff := cover.Difference(cov, maxCover[call.CallID]) diff = cover.Difference(diff, flakes) if len(diff) == 0 { return } inp1 := Input{p, inp.CallIndex, cov} corpus = append(corpus, inp1) corpusCover[call.CallID] = cover.Union(corpusCover[call.CallID], cov) maxCover[call.CallID] = cover.Union(maxCover[call.CallID], cov) corpusHashes[hash(inp.Prog)] = struct{}{} }
func addInput(inp RpcInput) { corpusMu.Lock() defer corpusMu.Unlock() coverMu.Lock() defer coverMu.Unlock() if noCover { panic("should not be called when coverage is disabled") } p, err := prog.Deserialize(inp.Prog) if err != nil { panic(err) } if inp.CallIndex < 0 || inp.CallIndex >= len(p.Calls) { panic("bad call index") } call := p.Calls[inp.CallIndex].Meta sig := hash(inp.Prog) if _, ok := corpusHashes[sig]; ok { return } cov := cover.Canonicalize(inp.Cover) diff := cover.Difference(cov, maxCover[call.CallID]) diff = cover.Difference(diff, flakes) if len(diff) == 0 { return } corpus = append(corpus, p) corpusCover[call.CallID] = cover.Union(corpusCover[call.CallID], cov) maxCover[call.CallID] = cover.Union(maxCover[call.CallID], cov) corpusHashes[hash(inp.Prog)] = struct{}{} }
func triageInput(env *ipc.Env, inp Input) { if *flagNoCover { panic("should not be called when coverage is disabled") } call := inp.p.Calls[inp.call].Meta newCover := cover.Difference(inp.cover, corpusCover[call.CallID]) newCover = cover.Difference(newCover, flakes) if len(newCover) == 0 { return } if _, ok := corpusHashes[hash(inp.p.Serialize())]; ok { return } minCover := inp.cover for i := 0; i < 3; i++ { allCover := execute1(env, inp.p, &statExecTriage) if len(allCover[inp.call]) == 0 { // The call was not executed. Happens sometimes, reason unknown. continue } cov := allCover[inp.call] diff := cover.SymmetricDifference(inp.cover, cov) if len(diff) != 0 { flakes = cover.Union(flakes, diff) } minCover = cover.Intersection(minCover, cov) } stableNewCover := cover.Intersection(newCover, minCover) if len(stableNewCover) == 0 { return } inp.p, inp.call = prog.Minimize(inp.p, inp.call, func(p1 *prog.Prog, call1 int) bool { allCover := execute1(env, p1, &statExecMinimize) if len(allCover[call1]) == 0 { return false // The call was not executed. } cov := allCover[call1] if len(cover.Intersection(stableNewCover, cov)) != len(stableNewCover) { return false } minCover = cover.Intersection(minCover, cov) return true }) inp.cover = minCover corpusCover[call.CallID] = cover.Union(corpusCover[call.CallID], minCover) corpus = append(corpus, inp) data := inp.p.Serialize() corpusHashes[hash(data)] = struct{}{} logf(2, "added new input for %v to corpus:\n%s", call.CallName, data) statNewInput++ a := &NewManagerInputArgs{*flagName, RpcInput{call.CallName, inp.p.Serialize(), inp.call, []uint32(inp.cover)}} if err := manager.Call("Manager.NewInput", a, nil); err != nil { panic(err) } }
func execute(env *ipc.Env, p *prog.Prog) { allCover := execute1(env, p) for i, cov := range allCover { if len(cov) == 0 { continue } c := p.Calls[i].Meta diff := cover.Difference(cov, maxCover[c.CallID]) diff = cover.Difference(diff, flakes) if len(diff) != 0 { triage = append(triage, Input{p.Clone(), i, cover.Copy(cov)}) } } }
func (mgr *Manager) NewInput(a *NewManagerInputArgs, r *int) error { logf(2, "new input from fuzzer %v", a.Name) mgr.mu.Lock() defer mgr.mu.Unlock() call := sys.CallID[a.Call] if len(cover.Difference(a.Cover, mgr.corpusCover[call])) == 0 { return nil } mgr.corpusCover[call] = cover.Union(mgr.corpusCover[call], a.Cover) mgr.corpus = append(mgr.corpus, a.RpcInput) mgr.stats["manager new inputs"]++ sig := hash(a.Prog) if _, ok := mgr.masterHashes[sig]; !ok { mgr.masterHashes[sig] = struct{}{} mgr.masterCorpus = append(mgr.masterCorpus, a.Prog) a1 := &NewMasterInputArgs{mgr.cfg.Name, a.Prog} if err := mgr.master.Call("Master.NewInput", a1, nil); err != nil { fatalf("call Master.NewInput failed: %v", err) } } return nil }
func (mgr *Manager) NewInput(a *NewInputArgs, r *int) error { Logf(2, "new input from %v for syscall %v", a.Name, a.Call) mgr.mu.Lock() defer mgr.mu.Unlock() f := mgr.fuzzers[a.Name] if f == nil { Fatalf("fuzzer %v is not connected", a.Name) } call := sys.CallID[a.Call] if len(cover.Difference(a.Cover, mgr.corpusCover[call])) == 0 { return nil } mgr.corpusCover[call] = cover.Union(mgr.corpusCover[call], a.Cover) mgr.corpus = append(mgr.corpus, a.RpcInput) mgr.stats["manager new inputs"]++ mgr.persistentCorpus.add(a.RpcInput.Prog) for _, f1 := range mgr.fuzzers { if f1 == f { continue } f1.inputs = append(f1.inputs, a.RpcInput) } return nil }
func execute(env *ipc.Env, p *prog.Prog, workerId int) []Input { allCover := execute1(env, p, workerId) var inputs []Input for i, cov := range allCover { if len(cov) == 0 { continue } c := p.Calls[i].Meta diff := cover.Difference(cov, maxCover[c.CallID]) diff = cover.Difference(diff, flakes) if len(diff) != 0 { p1 := p.Clone() p1.TrimAfter(i) inputs = append(inputs, Input{p1, i, cover.Copy(cov)}) } } return inputs }
func (mgr *Manager) NewInput(a *NewInputArgs, r *int) error { Logf(2, "new input from %v for syscall %v", a.Name, a.Call) mgr.mu.Lock() defer mgr.mu.Unlock() call := sys.CallID[a.Call] if len(cover.Difference(a.Cover, mgr.corpusCover[call])) == 0 { return nil } mgr.corpusCover[call] = cover.Union(mgr.corpusCover[call], a.Cover) mgr.corpus = append(mgr.corpus, a.RpcInput) mgr.stats["manager new inputs"]++ mgr.persistentCorpus.add(a.RpcInput.Prog) return nil }
func triageInput(pid int, env *ipc.Env, inp Input) { if noCover { panic("should not be called when coverage is disabled") } call := inp.p.Calls[inp.call].Meta coverMu.RLock() newCover := cover.Difference(inp.cover, corpusCover[call.CallID]) newCover = cover.Difference(newCover, flakes) coverMu.RUnlock() if len(newCover) == 0 { return } corpusMu.RLock() if _, ok := corpusHashes[hash(inp.p.Serialize())]; ok { corpusMu.RUnlock() return } corpusMu.RUnlock() minCover := inp.cover for i := 0; i < 3; i++ { allCover := execute1(pid, env, inp.p, &statExecTriage) if len(allCover[inp.call]) == 0 { // The call was not executed. Happens sometimes, reason unknown. continue } coverMu.RLock() cov := allCover[inp.call] diff := cover.SymmetricDifference(inp.cover, cov) minCover = cover.Intersection(minCover, cov) updateFlakes := len(diff) != 0 && len(cover.Difference(diff, flakes)) != 0 coverMu.RUnlock() if updateFlakes { coverMu.Lock() flakes = cover.Union(flakes, diff) coverMu.Unlock() } } stableNewCover := cover.Intersection(newCover, minCover) if len(stableNewCover) == 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(stableNewCover, cov)) != len(stableNewCover) { return false } minCover = cover.Intersection(minCover, cov) return true }, false) inp.cover = minCover atomic.AddUint64(&statNewInput, 1) data := inp.p.Serialize() Logf(2, "added new input for %v to corpus:\n%s", call.CallName, data) a := &NewInputArgs{*flagName, RpcInput{call.CallName, data, inp.call, []uint32(inp.cover)}} if err := manager.Call("Manager.NewInput", a, nil); err != nil { panic(err) } corpusMu.Lock() defer corpusMu.Unlock() coverMu.Lock() defer coverMu.Unlock() corpusCover[call.CallID] = cover.Union(corpusCover[call.CallID], minCover) corpus = append(corpus, inp.p) corpusHashes[hash(data)] = struct{}{} }