Beispiel #1
0
func initGCE() {
	var err error
	GCE, err = gce.NewContext()
	if err != nil {
		Fatalf("failed to init gce: %v", err)
	}
	Logf(0, "gce initialized: running on %v, internal IP %v, project %v, zone %v", GCE.Instance, GCE.InternalIP, GCE.ProjectID, GCE.ZoneID)
}
Beispiel #2
0
func main() {
	flag.Parse()
	cfg = readConfig(*flagConfig)
	EnableLogCaching(1000, 1<<20)
	initHttp(fmt.Sprintf(":%v", cfg.Http_Port))

	gopath, err := filepath.Abs("gopath")
	if err != nil {
		Fatalf("failed to get absolute path: %v", err)
	}
	os.Setenv("GOPATH", gopath)

	ctx = context.Background()
	storageClient, err = storage.NewClient(ctx)
	if err != nil {
		Fatalf("failed to create cloud storage client: %v", err)
	}

	GCE, err = gce.NewContext()
	if err != nil {
		Fatalf("failed to init gce: %v", err)
	}
	Logf(0, "gce initialized: running on %v, internal IP, %v project %v, zone %v", GCE.Instance, GCE.InternalIP, GCE.ProjectID, GCE.ZoneID)

	sigC := make(chan os.Signal, 2)
	signal.Notify(sigC, syscall.SIGINT, syscall.SIGUSR1)

	var managerCmd *exec.Cmd
	managerStopped := make(chan error)
	stoppingManager := false
	var lastImageUpdated time.Time
	var lastSyzkallerHash string
	var delayDuration time.Duration
	for {
		if delayDuration != 0 {
			Logf(0, "sleep for %v", delayDuration)
			select {
			case <-time.After(delayDuration):
			case err := <-managerStopped:
				if managerCmd == nil {
					Fatalf("spurious manager stop signal")
				}
				Logf(0, "syz-manager exited with %v", err)
				managerCmd = nil
				atomic.StoreUint32(&managerHttpPort, 0)
			case s := <-sigC:
				switch s {
				case syscall.SIGUSR1:
					// just poll for updates
					Logf(0, "SIGUSR1")
				case syscall.SIGINT:
					Logf(0, "SIGINT")
					if managerCmd != nil {
						Logf(0, "shutting down syz-manager...")
						managerCmd.Process.Signal(syscall.SIGINT)
						select {
						case err := <-managerStopped:
							if managerCmd == nil {
								Fatalf("spurious manager stop signal")
							}
							Logf(0, "syz-manager exited with %v", err)
						case <-sigC:
							managerCmd.Process.Kill()
						case <-time.After(time.Minute):
							managerCmd.Process.Kill()
						}
					}
					os.Exit(0)
				}
			}
		}
		delayDuration = 10 * time.Minute // assume that an error happened
		imageArchive, imageUpdated, err := openFile(cfg.Image_Archive)
		if err != nil {
			Logf(0, "%v", err)
			continue
		}
		syzkallerHash, err := updateSyzkallerBuild()
		if err != nil {
			Logf(0, "failed to update syzkaller: %v", err)
			continue
		}
		Logf(0, "image update time %v, syzkaller hash %v", imageUpdated, syzkallerHash)
		if lastImageUpdated == imageUpdated && lastSyzkallerHash == syzkallerHash && managerCmd != nil {
			delayDuration = time.Hour
			continue
		}

		if managerCmd != nil {
			if !stoppingManager {
				stoppingManager = true
				Logf(0, "stopping syz-manager...")
				managerCmd.Process.Signal(syscall.SIGINT)
			} else {
				Logf(0, "killing syz-manager...")
				managerCmd.Process.Kill()
			}
			delayDuration = time.Minute
			continue
		}

		if !*flagNoImageCreate && lastImageUpdated != imageUpdated {
			Logf(0, "downloading image archive...")
			if err := os.RemoveAll("image"); err != nil {
				Logf(0, "failed to remove image dir: %v", err)
				continue
			}
			if err := downloadAndExtract(imageArchive, "image"); err != nil {
				Logf(0, "failed to download and extract %v: %v", cfg.Image_Archive, err)
				continue
			}

			Logf(0, "uploading image...")
			if err := uploadFile("image/disk.tar.gz", cfg.Image_Path); err != nil {
				Logf(0, "failed to upload image: %v", err)
				continue
			}

			Logf(0, "creating gce image...")
			if err := GCE.DeleteImage(cfg.Image_Name); err != nil {
				Logf(0, "failed to delete GCE image: %v", err)
				continue
			}
			if err := GCE.CreateImage(cfg.Image_Name, cfg.Image_Path); err != nil {
				Logf(0, "failed to create GCE image: %v", err)
				continue
			}
		}
		*flagNoImageCreate = false
		lastImageUpdated = imageUpdated

		if !*flagNoRebuild && lastSyzkallerHash != syzkallerHash {
			Logf(0, "building syzkaller...")
			if err := buildSyzkaller(); err != nil {
				Logf(0, "failed to update/build syzkaller: %v", err)
				continue
			}
		}
		*flagNoRebuild = false
		lastSyzkallerHash = syzkallerHash

		port, err := chooseUnusedPort()
		if err != nil {
			Logf(0, "failed to choose an unused port: %v", err)
			continue
		}
		if err := writeManagerConfig(port, "manager.cfg"); err != nil {
			Logf(0, "failed to write manager config: %v", err)
			continue
		}

		Logf(0, "starting syz-manager (image %v, syzkaller %v)...", lastImageUpdated, lastSyzkallerHash)
		managerCmd = exec.Command("gopath/src/github.com/google/syzkaller/bin/syz-manager", "-config=manager.cfg")
		if err := managerCmd.Start(); err != nil {
			Logf(0, "failed to start syz-manager: %v", err)
			managerCmd = nil
			continue
		}
		stoppingManager = false
		atomic.StoreUint32(&managerHttpPort, uint32(port))
		go func() {
			managerStopped <- managerCmd.Wait()
		}()
		delayDuration = time.Hour
	}
}