mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-30 14:50:36 +00:00
607350e438
This commit adds a new attribute to syzkaller targets that tells syzkaller how to invoke the syz-executor command. Some systems, like Fuchsia, are now building syz-executor as part of the build, and there is no need to copy it over, or to run it from `/tmp`. In fact, that might stop working at some time in the future in Fuchsia. All places that used to copy syz-executor into the target machine will now check for the SyzExecutorCmd flag, and won't copy it if the flag is set.
131 lines
3.3 KiB
Go
131 lines
3.3 KiB
Go
// Copyright 2016 syzkaller project authors. All rights reserved.
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
// syz-crush replays crash log on multiple VMs. Usage:
|
|
// syz-crush -config=config.file execution.log
|
|
// Intended for reproduction of particularly elusive crashes.
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"io/ioutil"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/google/syzkaller/pkg/instance"
|
|
"github.com/google/syzkaller/pkg/log"
|
|
"github.com/google/syzkaller/pkg/mgrconfig"
|
|
"github.com/google/syzkaller/pkg/osutil"
|
|
"github.com/google/syzkaller/pkg/report"
|
|
"github.com/google/syzkaller/prog"
|
|
"github.com/google/syzkaller/sys/targets"
|
|
"github.com/google/syzkaller/vm"
|
|
)
|
|
|
|
var (
|
|
flagConfig = flag.String("config", "", "configuration file")
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
cfg, err := mgrconfig.LoadFile(*flagConfig)
|
|
if err != nil {
|
|
log.Fatalf("%v", err)
|
|
}
|
|
if len(flag.Args()) != 1 {
|
|
log.Fatalf("usage: syz-crush -config=config.file execution.log")
|
|
}
|
|
if _, err := prog.GetTarget(cfg.TargetOS, cfg.TargetArch); err != nil {
|
|
log.Fatalf("%v", err)
|
|
}
|
|
vmPool, err := vm.Create(cfg, false)
|
|
if err != nil {
|
|
log.Fatalf("%v", err)
|
|
}
|
|
reporter, err := report.NewReporter(cfg)
|
|
if err != nil {
|
|
log.Fatalf("%v", err)
|
|
}
|
|
|
|
log.Logf(0, "booting test machines...")
|
|
var shutdown uint32
|
|
var wg sync.WaitGroup
|
|
wg.Add(vmPool.Count() + 1)
|
|
for i := 0; i < vmPool.Count(); i++ {
|
|
i := i
|
|
go func() {
|
|
defer wg.Done()
|
|
for {
|
|
runInstance(cfg, reporter, vmPool, i)
|
|
if atomic.LoadUint32(&shutdown) != 0 {
|
|
break
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
shutdownC := make(chan struct{})
|
|
osutil.HandleInterrupts(shutdownC)
|
|
go func() {
|
|
<-shutdownC
|
|
wg.Done()
|
|
atomic.StoreUint32(&shutdown, 1)
|
|
}()
|
|
wg.Wait()
|
|
}
|
|
|
|
func runInstance(cfg *mgrconfig.Config, reporter report.Reporter, vmPool *vm.Pool, index int) {
|
|
inst, err := vmPool.Create(index)
|
|
if err != nil {
|
|
log.Logf(0, "failed to create instance: %v", err)
|
|
return
|
|
}
|
|
defer inst.Close()
|
|
|
|
execprogBin, err := inst.Copy(cfg.SyzExecprogBin)
|
|
if err != nil {
|
|
log.Logf(0, "failed to copy execprog: %v", err)
|
|
return
|
|
}
|
|
// If SyzExecutorCmd is provided, it means that syz-executor is already in
|
|
// the image, so no need to copy it.
|
|
executorCmd := targets.Get(cfg.TargetOS, cfg.TargetArch).SyzExecutorCmd
|
|
if executorCmd == "" {
|
|
executorCmd, err = inst.Copy(cfg.SyzExecutorBin)
|
|
if err != nil {
|
|
log.Logf(0, "failed to copy executor: %v", err)
|
|
return
|
|
}
|
|
}
|
|
logFile, err := inst.Copy(flag.Args()[0])
|
|
if err != nil {
|
|
log.Logf(0, "failed to copy log: %v", err)
|
|
return
|
|
}
|
|
|
|
cmd := instance.ExecprogCmd(execprogBin, executorCmd, cfg.TargetOS, cfg.TargetArch, cfg.Sandbox,
|
|
true, true, true, cfg.Procs, -1, -1, logFile)
|
|
outc, errc, err := inst.Run(time.Hour, nil, cmd)
|
|
if err != nil {
|
|
log.Logf(0, "failed to run execprog: %v", err)
|
|
return
|
|
}
|
|
|
|
log.Logf(0, "vm-%v: crushing...", index)
|
|
rep := inst.MonitorExecution(outc, errc, reporter, vm.ExitTimeout)
|
|
if rep == nil {
|
|
// This is the only "OK" outcome.
|
|
log.Logf(0, "vm-%v: running long enough, restarting", index)
|
|
} else {
|
|
f, err := ioutil.TempFile(".", "syz-crush")
|
|
if err != nil {
|
|
log.Logf(0, "failed to create temp file: %v", err)
|
|
return
|
|
}
|
|
defer f.Close()
|
|
log.Logf(0, "vm-%v: crashed: %v, saving to %v", index, rep.Title, f.Name())
|
|
f.Write(rep.Output)
|
|
}
|
|
}
|