From 8285069f89c9942f65ce760a8f0a5a12254bfeeb Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Sat, 18 May 2019 17:54:03 +0200 Subject: executor: implement support for leak checking Leak checking support was half done and did not really work. This is heavy-lifting to make it work. 1. Move leak/fault setup into executor. pkg/host was a wrong place for them because we need then in C repros too. The pkg/host periodic callback functionality did not work too, we need it in executor so that we can reuse it in C repros too. Remove setup/callback functions in pkg/host entirely. 2. Do leak setup/checking in C repros. The way leak checking is invoked is slightly different from fuzzer, but much better then no support at all. At least the checking code is shared. 3. Add Leak option to pkg/csource and -leak flag to syz-prog2c. 4. Don't enalbe leak checking in fuzzer while we are triaging initial corpus. It's toooo slow. 5. Fix pkg/repro to do something more sane for leak bugs. Few other minor fixes here and there. --- tools/syz-execprog/execprog.go | 29 ++++++++++++++--------------- tools/syz-prog2c/prog2c.go | 2 ++ tools/syz-stress/stress.go | 9 +++------ 3 files changed, 19 insertions(+), 21 deletions(-) (limited to 'tools') diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go index b2902ba14..5bebe8340 100644 --- a/tools/syz-execprog/execprog.go +++ b/tools/syz-execprog/execprog.go @@ -73,16 +73,25 @@ func main() { log.Logf(0, "%-24v: %v", feat.Name, feat.Reason) } } - if _, err = host.Setup(target, features); err != nil { - log.Fatalf("%v", err) - } config, execOpts := createConfig(target, entries, features, featuresFlags) - + if err = host.Setup(target, features, featuresFlags, config.Executor); err != nil { + log.Fatal(err) + } + var gateCallback func() + if features[host.FeatureLeakChecking].Enabled { + gateCallback = func() { + output, err := osutil.RunCmd(10*time.Minute, "", config.Executor, "leak") + if err != nil { + os.Stdout.Write(output) + os.Exit(1) + } + } + } ctx := &Context{ entries: entries, config: config, execOpts: execOpts, - gate: ipc.NewGate(2**flagProcs, nil), + gate: ipc.NewGate(2**flagProcs, gateCallback), shutdown: make(chan struct{}), repeat: *flagRepeat, } @@ -298,17 +307,10 @@ func createConfig(target *prog.Target, entries []*prog.LogEntry, config.Flags |= ipc.FlagExtraCover } if *flagFaultCall >= 0 { - config.Flags |= ipc.FlagEnableFault execOpts.Flags |= ipc.FlagInjectFault execOpts.FaultCall = *flagFaultCall execOpts.FaultNth = *flagFaultNth } - for _, entry := range entries { - if entry.Fault { - config.Flags |= ipc.FlagEnableFault - break - } - } if featuresFlags["tun"].Enabled && features[host.FeatureNetworkInjection].Enabled { config.Flags |= ipc.FlagEnableTun } @@ -321,9 +323,6 @@ func createConfig(target *prog.Target, entries []*prog.LogEntry, if featuresFlags["cgroups"].Enabled { config.Flags |= ipc.FlagEnableCgroups } - if featuresFlags["binfmt_misc"].Enabled { - config.Flags |= ipc.FlagEnableBinfmtMisc - } if featuresFlags["close_fds"].Enabled { config.Flags |= ipc.FlagEnableCloseFds } diff --git a/tools/syz-prog2c/prog2c.go b/tools/syz-prog2c/prog2c.go index 86f703c3b..0628468e5 100644 --- a/tools/syz-prog2c/prog2c.go +++ b/tools/syz-prog2c/prog2c.go @@ -32,6 +32,7 @@ var ( flagUseTmpDir = flag.Bool("tmpdir", false, "create a temporary dir and execute inside it") flagTrace = flag.Bool("trace", false, "trace syscall results") flagStrict = flag.Bool("strict", false, "parse input program in strict mode") + flagLeak = flag.Bool("leak", false, "do leak checking") flagEnable = flag.String("enable", "none", "enable only listed additional features") flagDisable = flag.String("disable", "none", "enable all additional features except listed") ) @@ -79,6 +80,7 @@ func main() { Fault: *flagFaultCall >= 0, FaultCall: *flagFaultCall, FaultNth: *flagFaultNth, + Leak: *flagLeak, EnableTun: features["tun"].Enabled, EnableNetDev: features["net_dev"].Enabled, EnableNetReset: features["net_reset"].Enabled, diff --git a/tools/syz-stress/stress.go b/tools/syz-stress/stress.go index 390a1fb4f..051f2870e 100644 --- a/tools/syz-stress/stress.go +++ b/tools/syz-stress/stress.go @@ -67,9 +67,6 @@ func main() { if err != nil { log.Fatalf("%v", err) } - if _, err = host.Setup(target, features); err != nil { - log.Fatalf("%v", err) - } calls := buildCallList(target, strings.Split(*flagSyscalls, ",")) prios := target.CalculatePriorities(corpus) @@ -91,12 +88,12 @@ func main() { if featuresFlags["cgroups"].Enabled { config.Flags |= ipc.FlagEnableCgroups } - if featuresFlags["binfmt_misc"].Enabled { - config.Flags |= ipc.FlagEnableBinfmtMisc - } if featuresFlags["close_fds"].Enabled { config.Flags |= ipc.FlagEnableCloseFds } + if err = host.Setup(target, features, featuresFlags, config.Executor); err != nil { + log.Fatal(err) + } gate = ipc.NewGate(2**flagProcs, nil) for pid := 0; pid < *flagProcs; pid++ { pid := pid -- cgit mrf-deployment