diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2022-03-31 18:26:42 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2022-04-29 17:16:33 +0200 |
| commit | a04ae3093de7eebc147770fe38a5bda96b5c0634 (patch) | |
| tree | 5d7062a73b354b5f1906847835e1c00804a572a5 /pkg/instance/instance.go | |
| parent | 7f2625f8905f7d981475fa314c3d06c56c7bd4b0 (diff) | |
all: use the same prog execution code throughout the project
Previously it was copypasted in pkg/instance, pkg/repro,
tools/syz-crash. Use the single implementation instead.
Also, this commit fixes a bug - the previous code always set collide to
true while reproducing a bug, which led to an immediate syz-exexprog's
exit. As a result, newer bugs with .syz repro only were never actually
reproduced on #syz test requests.
Diffstat (limited to 'pkg/instance/instance.go')
| -rw-r--r-- | pkg/instance/instance.go | 86 |
1 files changed, 24 insertions, 62 deletions
diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go index a3a87d338..218408191 100644 --- a/pkg/instance/instance.go +++ b/pkg/instance/instance.go @@ -360,30 +360,22 @@ func (inst *inst) testInstance() error { } func (inst *inst) testRepro() error { - cfg := inst.cfg - if len(inst.reproSyz) > 0 { - execprogBin, err := inst.vm.Copy(cfg.ExecprogBin) - if err != nil { - return &TestError{Title: fmt.Sprintf("failed to copy test binary to VM: %v", err)} - } - // If ExecutorBin is provided, it means that syz-executor is already in the image, - // so no need to copy it. - executorBin := cfg.SysTarget.ExecutorBin - if executorBin == "" { - executorBin, err = inst.vm.Copy(inst.cfg.ExecutorBin) - if err != nil { - return &TestError{Title: fmt.Sprintf("failed to copy test binary to VM: %v", err)} - } - } - progFile := filepath.Join(cfg.Workdir, "repro.prog") - if err := osutil.WriteFile(progFile, inst.reproSyz); err != nil { - return fmt.Errorf("failed to write temp file: %v", err) - } - vmProgFile, err := inst.vm.Copy(progFile) - if err != nil { - return &TestError{Title: fmt.Sprintf("failed to copy test binary to VM: %v", err)} + var err error + execProg, err := SetupExecProg(inst.vm, inst.cfg, inst.reporter, &OptionalConfig{ + OldFlagsCompatMode: !inst.optionalFlags, + }) + if err != nil { + return err + } + transformError := func(res *RunResult, err error) error { + if err != nil && res.Report != nil { + return &CrashError{Report: res.Report} } - opts, err := csource.DeserializeOptions(inst.reproOpts) + return err + } + if len(inst.reproSyz) > 0 { + var opts csource.Options + opts, err = csource.DeserializeOptions(inst.reproOpts) if err != nil { return err } @@ -394,47 +386,17 @@ func (inst *inst) testRepro() error { if opts.Sandbox == "" { opts.Sandbox = "none" } - if !opts.Fault { - opts.FaultCall = -1 - } - cmdSyz := ExecprogCmd(execprogBin, executorBin, cfg.TargetOS, cfg.TargetArch, opts.Sandbox, - true, true, opts.Collide, cfg.Procs, opts.FaultCall, opts.FaultNth, inst.optionalFlags, - cfg.Timeouts.Slowdown, vmProgFile) - if err := inst.testProgram(cmdSyz, cfg.Timeouts.NoOutputRunningTime); err != nil { - return err - } - } - if len(inst.reproC) == 0 { - return nil - } - bin, err := csource.BuildNoWarn(cfg.Target, inst.reproC) - if err != nil { - return err - } - defer os.Remove(bin) - vmBin, err := inst.vm.Copy(bin) - if err != nil { - return &TestError{Title: fmt.Sprintf("failed to copy test binary to VM: %v", err)} - } - // We should test for more than full "no output" timeout, but the problem is that C reproducers - // don't print anything, so we will get a false "no output" crash. - return inst.testProgram(vmBin, cfg.Timeouts.NoOutput/2) -} - -func (inst *inst) testProgram(command string, testTime time.Duration) error { - outc, errc, err := inst.vm.Run(testTime, nil, command) - if err != nil { - return fmt.Errorf("failed to run binary in VM: %v", err) - } - rep := inst.vm.MonitorExecution(outc, errc, inst.reporter, - vm.ExitTimeout|vm.ExitNormal|vm.ExitError) - if rep == nil { - return nil + opts.Repeat, opts.Threaded = true, true + err = transformError(execProg.RunSyzProg(inst.reproSyz, + inst.cfg.Timeouts.NoOutputRunningTime, opts)) } - if err := inst.reporter.Symbolize(rep); err != nil { - log.Logf(0, "failed to symbolize report: %v", err) + if err == nil && len(inst.reproC) > 0 { + // We should test for more than full "no output" timeout, but the problem is that C reproducers + // don't print anything, so we will get a false "no output" crash. + err = transformError(execProg.RunCProgRaw(inst.reproC, inst.cfg.Target, + inst.cfg.Timeouts.NoOutput/2)) } - return &CrashError{Report: rep} + return err } type OptionalFuzzerArgs struct { |
