Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}