// UpdateToNewSkiaVersion runs a series of commands to update the fuzzer to a new Skia Version. // It will stop the Generator, pause the Aggregator, update to the // new version, re-scan all previous fuzzes and then start the Generator and the Aggregator // again. It re-uses the Aggregator pipeline to do the re-analysis. func (v *VersionUpdater) UpdateToNewSkiaVersion(newHash string) (*vcsinfo.LongCommit, error) { oldHash := config.Generator.SkiaVersion.Hash // stop afl-fuzz StopBinaryGenerator() // sync skia to version, which sets config.Generator.SkiaVersion if err := common.DownloadSkia(newHash, config.Generator.SkiaRoot, &config.Generator); err != nil { return nil, fmt.Errorf("Could not sync skia to %s: %s", newHash, err) } // download all bad and grey fuzzes badFuzzNames, greyFuzzNames, err := v.downloadAllBadAndGreyFuzzes(oldHash, config.Aggregator.BinaryFuzzPath) if err != nil { return nil, fmt.Errorf("Problem downloading all previous fuzzes: %s", err) } glog.Infof("There are %d badFuzzNames and %d greyFuzzNames to rescan.", len(badFuzzNames), len(greyFuzzNames)) // This is a soft shutdown, i.e. it waits for aggregator's queues to be empty v.agg.ShutDown() if err := ClearBinaryGenerator(); err != nil { return nil, fmt.Errorf("Could not remove previous afl-fuzz results: %s", err) } if err := v.agg.RestartAnalysis(); err != nil { return nil, fmt.Errorf("Had problem restarting analysis/upload chain: %s", err) } // Reanalyze and reupload the fuzzes, making a bug on regressions. glog.Infof("Reanalyzing bad fuzzes") v.agg.MakeBugOnBadFuzz = false v.agg.UploadGreyFuzzes = true for _, name := range badFuzzNames { v.agg.ForceAnalysis(name) } v.agg.WaitForEmptyQueues() glog.Infof("Reanalyzing grey fuzzes") v.agg.MakeBugOnBadFuzz = true for _, name := range greyFuzzNames { v.agg.ForceAnalysis(name) } v.agg.WaitForEmptyQueues() v.agg.MakeBugOnBadFuzz = false v.agg.UploadGreyFuzzes = false glog.Infof("Done reanalyzing") // redownload samples (in case any are new) if err := DownloadBinarySeedFiles(v.storageClient); err != nil { return nil, fmt.Errorf("Could not download binary seed files: %s", err) } // change GCS version to have the current be up to date (fuzzer-fe will need to see that with its polling) if err := v.replaceCurrentSkiaVersionWith(oldHash, config.Generator.SkiaVersion.Hash); err != nil { return nil, fmt.Errorf("Could not update skia error: %s", err) } // restart afl-fuzz return config.Generator.SkiaVersion, StartBinaryGenerator() }
// HandleCurrentVersion sets the current version of Skia to be the specified value and calls // LoadFreshFromGoogleStorage. If there is an AST still being generated, it will block until // that completes. func (v *VersionUpdater) HandleCurrentVersion(currentHash string) (*vcsinfo.LongCommit, error) { // Make sure skia version is at the proper version. This also sets config.Frontend.SkiaVersion. if err := common.DownloadSkia(currentHash, config.FrontEnd.SkiaRoot, &config.FrontEnd); err != nil { return nil, fmt.Errorf("Could not update Skia to current version %s: %s", currentHash, err) } // Block until finder is built. v.finderBuilding.Lock() defer v.finderBuilding.Unlock() v.gsLoader.SetFinder(v.finders[currentHash]) if err := v.gsLoader.LoadFreshFromGoogleStorage(); err != nil { return nil, fmt.Errorf("Had problems fetching new fuzzes from GCS: %s", err) } v.syncer.Refresh() return config.FrontEnd.SkiaVersion, nil }
// HandlePendingVersion updates the frontend's copy of Skia to the specified pending version // and begins building the AST for the pending version on a background goroutine. func (v *VersionUpdater) HandlePendingVersion(pendingHash string) (*vcsinfo.LongCommit, error) { pending := versionHolder{} if err := common.DownloadSkia(pendingHash, config.FrontEnd.SkiaRoot, &pending); err != nil { return nil, fmt.Errorf("Could not update Skia to pending version %s: %s", pendingHash, err) } // start generating AST in the background. go func() { v.finderBuilding.Lock() defer v.finderBuilding.Unlock() if finder, err := functionnamefinder.NewSync(); err != nil { glog.Errorf("Error building FunctionNameFinder at version %s: %s", pendingHash, err) return } else { glog.Infof("Successfully rebuilt AST for Skia version %s", pendingHash) v.finders[pendingHash] = finder } }() return pending.version, nil }