二 Syzkaller学习笔记---更新syz-manager(14)


有一些其他的参数
debug 参数和 bench参数 debug参数将VM所有输出打印到帮助我们排查使用中出现的错误;bench参数定期将执行的统计信息写入我们指定的文件 。
var (flagConfig = flag.String("config", "", "configuration file")flagDebug= flag.Bool("debug", false, "dump all VM output to console")flagBench= flag.String("bench", "", "write execution statistics into this file periodically"))
main
syz-manager/manager.go
功能:开启日志缓存,加载文件,调用
func main() {if prog.GitRevision == "" {log.Fatalf("bad syz-manager build: build with make, run bin/syz-manager")}flag.Parse()log.EnableLogCaching(1000, 1<<20)//开启日志缓存,提高性能,超过1000行会被覆盖,或者 1MB 超过丢弃cfg, err := mgrconfig.LoadFile(*flagConfig)//加载 config文件if err != nil {log.Fatalf("%v", err)}RunManager(cfg)//接着分析}
(cfg)
功能:新开线程,定期记录VM状态,crash数量等信息,最后调用()
func RunManager(cfg *mgrconfig.Config) {var vmPool *vm.Pool// Type "none" is a special case for debugging/development when manager// does not start any VMs, but instead you start them manually// and start syz-fuzzer there.if cfg.Type != "none" {// 将type指定为none是在调试/开发中用的,这样manager就不会启动VM而是需要手动启动var err errorvmPool, err = vm.Create(cfg, *flagDebug)//创建 vmPool,一个vmpool可用于创建多个独立的VM,vm.go 对不同的虚拟化方案提供了统一的接口,会调用qemu.go:Ctor 函数 主要检查一些参数if err != nil {log.Fatalf("%v", err)}}//crashdir 很明白crashdir := filepath.Join(cfg.Workdir, "crashes")osutil.MkdirAll(crashdir)//reporter导出reporter, err := report.NewReporter(cfg)if err != nil {log.Fatalf("%v", err)}mgr := &Manager{cfg:cfg,vmPool:vmPool,target:cfg.Target,sysTarget:cfg.SysTarget,reporter:reporter,crashdir:crashdir,startTime:time.Now(),stats:&Stats{haveHub: cfg.HubClient != ""},crashTypes:make(map[string]bool),corpus:make(map[string]CorpusItem),disabledHashes:make(map[string]struct{}),memoryLeakFrames: make(map[string]bool),dataRaceFrames:make(map[string]bool),fresh:true,vmStop:make(chan bool),hubReproQueue:make(chan *Crash, 10),needMoreRepros:make(chan chan bool),reproRequest:make(chan chan map[string]bool),usedFiles:make(map[string]time.Time),saturatedCalls:make(map[string]bool),}mgr.preloadCorpus()mgr.initStats() // Initializes prometheus variables.mgr.initHTTP()// Creates HTTP server.mgr.collectUsedFiles()// Create RPC server for fuzzers.mgr.serv, err = startRPCServer(mgr)if err != nil {log.Fatalf("failed to create rpc server: %v", err)}if cfg.DashboardAddr != "" {mgr.dash, err = dashapi.New(cfg.DashboardClient, cfg.DashboardAddr, cfg.DashboardKey)if err != nil {log.Fatalf("failed to create dashapi connection: %v", err)}}if !cfg.AssetStorage.IsEmpty() {mgr.assetStorage, err = asset.StorageFromConfig(cfg.AssetStorage, mgr.dash)if err != nil {log.Fatalf("failed to init asset storage: %v", err)}}go func() { // [2] 新开线程,定期记录VM状态、crash数量等信息for lastTime := time.Now(); ; {time.Sleep(10 * time.Second)now := time.Now()diff := now.Sub(lastTime)lastTime = nowmgr.mu.Lock()if mgr.firstConnect.IsZero() {mgr.mu.Unlock()continue}mgr.fuzzingTime += diff * time.Duration(atomic.LoadUint32(&mgr.numFuzzing))executed := mgr.stats.execTotal.get()crashes := mgr.stats.crashes.get()corpusCover := mgr.stats.corpusCover.get()corpusSignal := mgr.stats.corpusSignal.get()maxSignal := mgr.stats.maxSignal.get()mgr.mu.Unlock()numReproducing := atomic.LoadUint32(&mgr.numReproducing)numFuzzing := atomic.LoadUint32(&mgr.numFuzzing)log.Logf(0, "VMs %v, executed %v, cover %v, signal %v/%v, crashes %v, repro %v",numFuzzing, executed, corpusCover, corpusSignal, maxSignal, crashes, numReproducing)}}()if *flagBench != "" {//如果设置了 bench 参数,还要在指定的文件中记录一些信息 。mgr.initBench()}if mgr.dash != nil {go mgr.dashboardReporter()}osutil.HandleInterrupts(vm.Shutdown)if mgr.vmPool == nil {log.Logf(0, "no VMs started (type=none)")log.Logf(0, "you are supposed to start syz-fuzzer manually as:")log.Logf(0, "syz-fuzzer -manager=manager.ip:%v [other flags as necessary]", mgr.serv.port)