aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/repro/repro.go17
-rw-r--r--prog/encoding_test.go4
-rw-r--r--prog/minimization.go2
-rw-r--r--prog/mutation_test.go22
-rw-r--r--prog/prog_test.go4
-rw-r--r--syz-fuzzer/proc.go27
6 files changed, 39 insertions, 37 deletions
diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go
index bbe0e2d7c..fc79f5a8a 100644
--- a/pkg/repro/repro.go
+++ b/pkg/repro/repro.go
@@ -428,14 +428,15 @@ func (ctx *context) minimizeProg(res *Result) (*Result, error) {
if res.Opts.Fault {
call = res.Opts.FaultCall
}
- res.Prog, res.Opts.FaultCall = prog.Minimize(res.Prog, call, func(p1 *prog.Prog, callIndex int) bool {
- crashed, err := ctx.testProg(p1, res.Duration, res.Opts)
- if err != nil {
- ctx.reproLog(0, "minimization failed with %v", err)
- return false
- }
- return crashed
- }, true)
+ res.Prog, res.Opts.FaultCall = prog.Minimize(res.Prog, call, true,
+ func(p1 *prog.Prog, callIndex int) bool {
+ crashed, err := ctx.testProg(p1, res.Duration, res.Opts)
+ if err != nil {
+ ctx.reproLog(0, "minimization failed with %v", err)
+ return false
+ }
+ return crashed
+ })
return res, nil
}
diff --git a/prog/encoding_test.go b/prog/encoding_test.go
index da90c6bbe..ffe6f4156 100644
--- a/prog/encoding_test.go
+++ b/prog/encoding_test.go
@@ -198,10 +198,10 @@ func TestSerializeDeserializeRandom(t *testing.T) {
if ok, _, _ := testSerializeDeserialize(t, p0, data0, data1); ok {
continue
}
- p0, _ = Minimize(p0, -1, func(p1 *Prog, _ int) bool {
+ p0, _ = Minimize(p0, -1, false, func(p1 *Prog, _ int) bool {
ok, _, _ := testSerializeDeserialize(t, p1, data0, data1)
return !ok
- }, false)
+ })
ok, n0, n1 := testSerializeDeserialize(t, p0, data0, data1)
if ok {
t.Fatal("flaky?")
diff --git a/prog/minimization.go b/prog/minimization.go
index 459e6265d..8a77eec03 100644
--- a/prog/minimization.go
+++ b/prog/minimization.go
@@ -11,7 +11,7 @@ import (
// predicate pred. It iteratively generates simpler programs and asks pred
// whether it is equal to the orginal program or not. If it is equivalent then
// the simplification attempt is committed and the process continues.
-func Minimize(p0 *Prog, callIndex0 int, pred0 func(*Prog, int) bool, crash bool) (*Prog, int) {
+func Minimize(p0 *Prog, callIndex0 int, crash bool, pred0 func(*Prog, int) bool) (*Prog, int) {
pred := pred0
if debug {
pred = func(p *Prog, callIndex int) bool {
diff --git a/prog/mutation_test.go b/prog/mutation_test.go
index 72f0e3cac..6452eddfa 100644
--- a/prog/mutation_test.go
+++ b/prog/mutation_test.go
@@ -301,7 +301,7 @@ func TestMinimize(t *testing.T) {
if err != nil {
t.Fatalf("failed to deserialize original program #%v: %v", ti, err)
}
- p1, ci := Minimize(p, test.callIndex, test.pred, false)
+ p1, ci := Minimize(p, test.callIndex, false, test.pred)
res := p1.Serialize()
if string(res) != test.result {
t.Fatalf("minimization produced wrong result #%v\norig:\n%v\nexpect:\n%v\ngot:\n%v\n",
@@ -319,21 +319,21 @@ func TestMinimizeRandom(t *testing.T) {
iters /= 10 // Long test.
for i := 0; i < iters; i++ {
p := target.Generate(rs, 5, nil)
- Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool {
+ Minimize(p, len(p.Calls)-1, true, func(p1 *Prog, callIndex int) bool {
return false
- }, true)
- Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool {
+ })
+ Minimize(p, len(p.Calls)-1, true, func(p1 *Prog, callIndex int) bool {
return true
- }, true)
+ })
}
for i := 0; i < iters; i++ {
p := target.Generate(rs, 5, nil)
- Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool {
+ Minimize(p, len(p.Calls)-1, false, func(p1 *Prog, callIndex int) bool {
return false
- }, false)
- Minimize(p, len(p.Calls)-1, func(p1 *Prog, callIndex int) bool {
+ })
+ Minimize(p, len(p.Calls)-1, false, func(p1 *Prog, callIndex int) bool {
return true
- }, false)
+ })
}
}
@@ -343,9 +343,9 @@ func TestMinimizeCallIndex(t *testing.T) {
for i := 0; i < iters; i++ {
p := target.Generate(rs, 5, nil)
ci := r.Intn(len(p.Calls))
- p1, ci1 := Minimize(p, ci, func(p1 *Prog, callIndex int) bool {
+ p1, ci1 := Minimize(p, ci, r.Intn(2) == 0, func(p1 *Prog, callIndex int) bool {
return r.Intn(2) == 0
- }, r.Intn(2) == 0)
+ })
if ci1 < 0 || ci1 >= len(p1.Calls) || p.Calls[ci].Meta.Name != p1.Calls[ci1].Meta.Name {
t.Fatalf("bad call index after minimization")
}
diff --git a/prog/prog_test.go b/prog/prog_test.go
index 4d9baff62..146694f45 100644
--- a/prog/prog_test.go
+++ b/prog/prog_test.go
@@ -157,9 +157,9 @@ func testCrossTarget(t *testing.T, target *Target, crossTargets []*Target) {
testCrossArchProg(t, p, crossTargets)
p.Mutate(rs, 20, nil, nil)
testCrossArchProg(t, p, crossTargets)
- p, _ = Minimize(p, -1, func(*Prog, int) bool {
+ p, _ = Minimize(p, -1, false, func(*Prog, int) bool {
return rs.Int63()%2 == 0
- }, false)
+ })
testCrossArchProg(t, p, crossTargets)
}
}
diff --git a/syz-fuzzer/proc.go b/syz-fuzzer/proc.go
index 9653662f3..5d280435b 100644
--- a/syz-fuzzer/proc.go
+++ b/syz-fuzzer/proc.go
@@ -138,20 +138,21 @@ func (proc *Proc) triageInput(item *WorkTriage) {
}
}
if !item.minimized {
- item.p, item.call = prog.Minimize(item.p, item.call, func(p1 *prog.Prog, call1 int) bool {
- for i := 0; i < minimizeAttempts; i++ {
- info := proc.execute(execOpts, p1, false, false, false, false, true, StatMinimize)
- if len(info) == 0 || len(info[call1].Signal) == 0 {
- continue // The call was not executed.
+ item.p, item.call = prog.Minimize(item.p, item.call, false,
+ func(p1 *prog.Prog, call1 int) bool {
+ for i := 0; i < minimizeAttempts; i++ {
+ info := proc.execute(execOpts, p1, false, false, false, false, true, StatMinimize)
+ if len(info) == 0 || len(info[call1].Signal) == 0 {
+ continue // The call was not executed.
+ }
+ inf := info[call1]
+ signal := cover.Canonicalize(inf.Signal)
+ if len(cover.Intersection(newSignal, signal)) == len(newSignal) {
+ return true
+ }
}
- inf := info[call1]
- signal := cover.Canonicalize(inf.Signal)
- if len(cover.Intersection(newSignal, signal)) == len(newSignal) {
- return true
- }
- }
- return false
- }, false)
+ return false
+ })
}
data := item.p.Serialize()