func (mgr *Manager) runInstance(vmCfg *vm.Config, first bool) bool { inst, err := vm.Create(mgr.cfg.Type, vmCfg) if err != nil { Logf(0, "failed to create instance: %v", err) return false } defer inst.Close() fwdAddr, err := inst.Forward(mgr.port) if err != nil { Logf(0, "failed to setup port forwarding: %v", err) return false } fuzzerBin, err := inst.Copy(filepath.Join(mgr.cfg.Syzkaller, "bin", "syz-fuzzer")) if err != nil { Logf(0, "failed to copy binary: %v", err) return false } executorBin, err := inst.Copy(filepath.Join(mgr.cfg.Syzkaller, "bin", "syz-executor")) if err != nil { Logf(0, "failed to copy binary: %v", err) return false } // Leak detection significantly slows down fuzzing, so detect leaks only on the first instance. leak := first && mgr.cfg.Leak fuzzerV := 0 if *flagDebug { fuzzerV = 100 } // Run the fuzzer binary. outc, errc, err := inst.Run(time.Hour, fmt.Sprintf( "%v -executor=%v -name=%v -manager=%v -output=%v -procs=%v -leak=%v -cover=%v -sandbox=%v -debug=%v -v=%d", fuzzerBin, executorBin, vmCfg.Name, fwdAddr, mgr.cfg.Output, mgr.cfg.Procs, leak, mgr.cfg.Cover, mgr.cfg.Sandbox, *flagDebug, fuzzerV)) if err != nil { Logf(0, "failed to run fuzzer: %v", err) return false } desc, text, output, crashed, timedout := vm.MonitorExecution(outc, errc, mgr.cfg.Type == "local", true) if timedout { // This is the only "OK" outcome. Logf(0, "%v: running long enough, restarting", vmCfg.Name) } else { if !crashed { // syz-fuzzer exited, but it should not. desc = "lost connection to test machine" } mgr.saveCrasher(vmCfg, desc, text, output) } return true }
func runInstance(cfg *config.Config, vmCfg *vm.Config) { inst, err := vm.Create(cfg.Type, vmCfg) if err != nil { Logf(0, "failed to create instance: %v", err) return } defer inst.Close() execprogBin, err := inst.Copy(filepath.Join(cfg.Syzkaller, "bin", "syz-execprog")) if err != nil { Logf(0, "failed to copy execprog: %v", err) return } executorBin, err := inst.Copy(filepath.Join(cfg.Syzkaller, "bin", "syz-executor")) if err != nil { Logf(0, "failed to copy executor: %v", err) return } logFile, err := inst.Copy(flag.Args()[0]) if err != nil { Logf(0, "failed to copy log: %v", err) return } cmd := fmt.Sprintf("%v -executor=%v -repeat=0 -procs=%v -cover=0 -sandbox=%v %v", execprogBin, executorBin, cfg.Procs, cfg.Sandbox, logFile) outc, errc, err := inst.Run(time.Hour, nil, cmd) if err != nil { Logf(0, "failed to run execprog: %v", err) return } Logf(0, "%v: crushing...", vmCfg.Name) desc, _, output, crashed, timedout := vm.MonitorExecution(outc, errc, cfg.Type == "local", true, cfg.ParsedIgnores) if timedout { // This is the only "OK" outcome. Logf(0, "%v: running long enough, restarting", vmCfg.Name) } else { if !crashed { // syz-execprog exited, but it should not. desc = "lost connection to test machine" } f, err := ioutil.TempFile(".", "syz-crush") if err != nil { Logf(0, "failed to create temp file: %v", err) return } defer f.Close() Logf(0, "%v: crashed: %v, saving to %v", vmCfg.Name, desc, f.Name()) f.Write(output) } return }
func (ctx *context) testImpl(inst vm.Instance, command string, duration time.Duration) (crashed bool, err error) { outc, errc, err := inst.Run(duration, nil, command) if err != nil { return false, fmt.Errorf("failed to run command in VM: %v", err) } desc, text, output, crashed, timedout := vm.MonitorExecution(outc, errc, false, false, ctx.cfg.ParsedIgnores) _, _, _ = text, output, timedout if !crashed { Logf(2, "reproducing crash '%v': program did not crash", ctx.crashDesc) return false, nil } Logf(2, "reproducing crash '%v': program crashed: %v", ctx.crashDesc, desc) return true, nil }
func (mgr *Manager) runInstance(vmCfg *vm.Config, first bool) (*Crash, error) { inst, err := vm.Create(mgr.cfg.Type, vmCfg) if err != nil { return nil, fmt.Errorf("failed to create instance: %v", err) } defer inst.Close() fwdAddr, err := inst.Forward(mgr.port) if err != nil { return nil, fmt.Errorf("failed to setup port forwarding: %v", err) } fuzzerBin, err := inst.Copy(filepath.Join(mgr.cfg.Syzkaller, "bin", "syz-fuzzer")) if err != nil { return nil, fmt.Errorf("failed to copy binary: %v", err) } executorBin, err := inst.Copy(filepath.Join(mgr.cfg.Syzkaller, "bin", "syz-executor")) if err != nil { return nil, fmt.Errorf("failed to copy binary: %v", err) } // Leak detection significantly slows down fuzzing, so detect leaks only on the first instance. leak := first && mgr.cfg.Leak fuzzerV := 0 procs := mgr.cfg.Procs if *flagDebug { fuzzerV = 100 procs = 1 } // Run the fuzzer binary. start := time.Now() cmd := fmt.Sprintf("%v -executor=%v -name=%v -manager=%v -output=%v -procs=%v -leak=%v -cover=%v -sandbox=%v -debug=%v -v=%d", fuzzerBin, executorBin, vmCfg.Name, fwdAddr, mgr.cfg.Output, procs, leak, mgr.cfg.Cover, mgr.cfg.Sandbox, *flagDebug, fuzzerV) outc, errc, err := inst.Run(time.Hour, mgr.vmStop, cmd) if err != nil { return nil, fmt.Errorf("failed to run fuzzer: %v", err) } desc, text, output, crashed, timedout := vm.MonitorExecution(outc, errc, mgr.cfg.Type == "local", true, mgr.cfg.ParsedIgnores) if timedout { // This is the only "OK" outcome. Logf(0, "%v: running for %v, restarting (%v)", vmCfg.Name, time.Since(start), desc) return nil, nil } if !crashed { // syz-fuzzer exited, but it should not. desc = "lost connection to test machine" } return &Crash{vmCfg.Name, desc, text, output}, nil }
func testImpl(inst vm.Instance, command string, timeout time.Duration) (res bool) { outc, errc, err := inst.Run(timeout, command) if err != nil { Fatalf("failed to run command in VM: %v", err) } desc, text, output, crashed, timedout := vm.MonitorExecution(outc, errc, false, false) _, _ = text, output if crashed || timedout { Logf(0, "program crashed with: %v", desc) return true } Logf(0, "program did not crash") return false }