aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-03-28 17:08:04 +0100
committerDmitry Vyukov <dvyukov@google.com>2024-04-03 11:26:05 +0000
commitafbcc4a93d840f52b2579530d638654a4a1e5447 (patch)
treec2dcaea20bb86ba9cd1626516da4a1bfd79a3b98
parent77aa13ea89f1d7c7df4a17a6a83a11bf965d38d3 (diff)
pkg/fuzzer: don't triage saturated calls
Currently we throw away saturated calls only after triage/minimization. Triage/minimization is unnecessary for saturated calls, we already know we will throw them away later. Don't send saturated calls for triage/minimization.
-rw-r--r--pkg/corpus/corpus.go13
-rw-r--r--pkg/fuzzer/fuzzer.go10
-rw-r--r--pkg/fuzzer/job.go16
-rw-r--r--prog/prog.go10
-rw-r--r--syz-manager/manager.go4
5 files changed, 28 insertions, 25 deletions
diff --git a/pkg/corpus/corpus.go b/pkg/corpus/corpus.go
index 568da832b..c513d2303 100644
--- a/pkg/corpus/corpus.go
+++ b/pkg/corpus/corpus.go
@@ -59,14 +59,7 @@ type Item struct {
}
func (item Item) StringCall() string {
- return stringCall(item.Prog, item.Call)
-}
-
-func stringCall(p *prog.Prog, call int) string {
- if call != -1 {
- return p.Calls[call].Meta.Name
- }
- return ".extra"
+ return item.Prog.CallName(item.Call)
}
type NewInput struct {
@@ -77,10 +70,6 @@ type NewInput struct {
RawCover []uint32
}
-func (item NewInput) StringCall() string {
- return stringCall(item.Prog, item.Call)
-}
-
type NewItemEvent struct {
Sig string
Exists bool
diff --git a/pkg/fuzzer/fuzzer.go b/pkg/fuzzer/fuzzer.go
index df6fbd598..6a1df6ba6 100644
--- a/pkg/fuzzer/fuzzer.go
+++ b/pkg/fuzzer/fuzzer.go
@@ -43,6 +43,11 @@ type Fuzzer struct {
func NewFuzzer(ctx context.Context, cfg *Config, rnd *rand.Rand,
target *prog.Target) *Fuzzer {
+ if cfg.NewInputFilter == nil {
+ cfg.NewInputFilter = func(call string) bool {
+ return true
+ }
+ }
f := &Fuzzer{
Config: cfg,
Cover: &Cover{},
@@ -77,7 +82,7 @@ type Config struct {
EnabledCalls map[*prog.Syscall]bool
NoMutateCalls map[int]bool
FetchRawCover bool
- NewInputFilter func(input *corpus.NewInput) bool
+ NewInputFilter func(call string) bool
}
type Request struct {
@@ -131,6 +136,9 @@ func (fuzzer *Fuzzer) triageProgCall(p *prog.Prog, info *ipc.CallInfo, call int,
fuzzer.Logf(2, "found new flaky signal in call %d in %s", call, p)
return
}
+ if !fuzzer.Config.NewInputFilter(p.CallName(call)) {
+ return
+ }
fuzzer.Logf(2, "found new signal in call %d in %s", call, p)
fuzzer.startJob(&triageJob{
p: p.Clone(),
diff --git a/pkg/fuzzer/job.go b/pkg/fuzzer/job.go
index a0412126f..b5c8b9f32 100644
--- a/pkg/fuzzer/job.go
+++ b/pkg/fuzzer/job.go
@@ -131,12 +131,8 @@ func triageJobPrio(flags ProgTypes) jobPriority {
}
func (job *triageJob) run(fuzzer *Fuzzer) {
- logCallName := "extra"
- if job.call != -1 {
- callName := job.p.Calls[job.call].Meta.Name
- logCallName = fmt.Sprintf("call #%v %v", job.call, callName)
- }
- fuzzer.Logf(3, "triaging input for %v (new signal=%v)", logCallName, job.newSignal.Len())
+ callName := fmt.Sprintf("call #%v %v", job.call, job.p.CallName(job.call))
+ fuzzer.Logf(3, "triaging input for %v (new signal=%v)", callName, job.newSignal.Len())
// Compute input coverage and non-flaky signal for minimization.
info, stop := job.deflake(fuzzer)
if stop || info.newStableSignal.Empty() {
@@ -148,7 +144,10 @@ func (job *triageJob) run(fuzzer *Fuzzer) {
return
}
}
- fuzzer.Logf(2, "added new input for %q to the corpus:\n%s", logCallName, job.p.String())
+ if !fuzzer.Config.NewInputFilter(job.p.CallName(job.call)) {
+ return
+ }
+ fuzzer.Logf(2, "added new input for %v to the corpus: %s", callName, job.p)
if job.flags&progSmashed == 0 {
fuzzer.startJob(&smashJob{
p: job.p.Clone(),
@@ -162,9 +161,6 @@ func (job *triageJob) run(fuzzer *Fuzzer) {
Cover: info.cover.Serialize(),
RawCover: info.rawCover,
}
- if filter := fuzzer.Config.NewInputFilter; filter != nil && !filter(&input) {
- return
- }
fuzzer.Config.Corpus.Save(input)
}
diff --git a/prog/prog.go b/prog/prog.go
index 6b4853c7a..880e02eeb 100644
--- a/prog/prog.go
+++ b/prog/prog.go
@@ -14,6 +14,16 @@ type Prog struct {
Comments []string
}
+func (p *Prog) CallName(call int) string {
+ if call >= len(p.Calls) || call < -1 {
+ panic(fmt.Sprintf("bad call index %v/%v", call, len(p.Calls)))
+ }
+ if call == -1 {
+ return ".extra"
+ }
+ return p.Calls[call].Meta.Name
+}
+
// These properties are parsed and serialized according to the tag and the type
// of the corresponding fields.
// IMPORTANT: keep the exact values of "key" tag for existing props unchanged,
diff --git a/syz-manager/manager.go b/syz-manager/manager.go
index 3f7cb1254..2280cf287 100644
--- a/syz-manager/manager.go
+++ b/syz-manager/manager.go
@@ -1409,10 +1409,10 @@ func (mgr *Manager) machineChecked(a *rpctype.CheckArgs, enabledSyscalls map[*pr
}
log.Logf(level, msg, args...)
},
- NewInputFilter: func(input *corpus.NewInput) bool {
+ NewInputFilter: func(call string) bool {
mgr.mu.Lock()
defer mgr.mu.Unlock()
- return !mgr.saturatedCalls[input.StringCall()]
+ return !mgr.saturatedCalls[call]
},
}, rnd, mgr.target)
mgr.fuzzer.Store(fuzzerObj)