From 32e29dda2cf82b0dab7408bdef4c0af4d0a7fef8 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 9 Aug 2017 13:11:14 +0200 Subject: [PATCH] pkg/repro: fix invalid options minimization Repro can generate Sandbox="namespace"/UseTmpDir=false. This combination is broken for two reasons: - on second and subsequent executions of the program, it fails to create syz-tmp dir - with Procs>1, it fails right away, because all procs try to create syz-tmp dir Don't generate such combination. --- pkg/csource/csource.go | 8 ++++++++ pkg/csource/csource_test.go | 13 +++++++------ pkg/repro/repro.go | 2 +- pkg/repro/repro_test.go | 17 +++++++++++------ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index e351a2e1..163a9b06 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -51,11 +51,19 @@ type Options struct { // Invalid combinations must not be passed to Write. func (opts Options) Check() error { if !opts.Threaded && opts.Collide { + // Collide requires threaded. return errors.New("Collide without Threaded") } if !opts.Repeat && opts.Procs > 1 { + // This does not affect generated code. return errors.New("Procs>1 without Repeat") } + if opts.Sandbox == "namespace" && !opts.UseTmpDir { + // This is borken and never worked. + // This tries to create syz-tmp dir in cwd, + // which will fail if procs>1 and on second run of the program. + return errors.New("Sandbox=namespace without UseTmpDir") + } return nil } diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go index ae34a949..e4e9e1f7 100644 --- a/pkg/csource/csource_test.go +++ b/pkg/csource/csource_test.go @@ -85,12 +85,13 @@ func allOptionsPermutations() []Options { func TestOne(t *testing.T) { rs, _ := initTest(t) opts := Options{ - Threaded: true, - Collide: true, - Repeat: true, - Procs: 2, - Sandbox: "namespace", - Repro: true, + Threaded: true, + Collide: true, + Repeat: true, + Procs: 2, + Sandbox: "namespace", + Repro: true, + UseTmpDir: true, } p := prog.GenerateAllSyzProg(rs) testOne(t, p, opts) diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go index 15481296..0b4581ff 100644 --- a/pkg/repro/repro.go +++ b/pkg/repro/repro.go @@ -792,7 +792,7 @@ var cSimplifies = append(progSimplifies, []Simplify{ return true }, func(opts *csource.Options) bool { - if !opts.UseTmpDir { + if !opts.UseTmpDir || opts.Sandbox == "namespace" { return false } opts.UseTmpDir = false diff --git a/pkg/repro/repro_test.go b/pkg/repro/repro_test.go index 3334db77..e56e176a 100644 --- a/pkg/repro/repro_test.go +++ b/pkg/repro/repro_test.go @@ -78,13 +78,18 @@ func TestSimplifies(t *testing.T) { WaitRepeat: true, Repro: true, } - if err := opts.Check(); err != nil { - t.Fatalf("initial opts are invalid: %v", err) - } - for i, fn := range cSimplifies { - fn(&opts) + var check func(opts csource.Options, i int) + check = func(opts csource.Options, i int) { if err := opts.Check(); err != nil { - t.Fatalf("opts %v are invalid: %v", i, err) + t.Fatalf("opts are invalid: %v", err) + } + if i == len(cSimplifies) { + return + } + check(opts, i+1) + if cSimplifies[i](&opts) { + check(opts, i+1) } } + check(opts, 0) }