| OLD | NEW |
| 1 package main | 1 package main |
| 2 | 2 |
| 3 /* | 3 /* |
| 4 Runs the backend portions of the fuzzer. This includes the generator and aggreg
ator parts (see DESIGN.md) | 4 Runs the backend portions of the fuzzer. This includes the generator and aggreg
ator parts (see DESIGN.md) |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "flag" | 8 "flag" |
| 9 "fmt" | 9 "fmt" |
| 10 "os" | 10 "os" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 var ( | 28 var ( |
| 29 aflOutputPath = flag.String("afl_output_path", "", "[REQUIRED] The
output folder of afl-fuzz. This will have on folder for each fuzz_to_run. Each
of those will have N folders named fuzzer0 - fuzzerN. Should not be in /tmp or
afl-fuzz will refuse to run.") | 29 aflOutputPath = flag.String("afl_output_path", "", "[REQUIRED] The
output folder of afl-fuzz. This will have on folder for each fuzz_to_run. Each
of those will have N folders named fuzzer0 - fuzzerN. Should not be in /tmp or
afl-fuzz will refuse to run.") |
| 30 generatorWD = flag.String("generator_working_dir", "", "[REQUIRED
] The generator's working directory. Should not be in /tmp.") | 30 generatorWD = flag.String("generator_working_dir", "", "[REQUIRED
] The generator's working directory. Should not be in /tmp.") |
| 31 fuzzSamples = flag.String("fuzz_samples", "", "[REQUIRED] The gen
erator's working directory. Should not be in /tmp.") | 31 fuzzSamples = flag.String("fuzz_samples", "", "[REQUIRED] The gen
erator's working directory. Should not be in /tmp.") |
| 32 skiaRoot = flag.String("skia_root", "", "[REQUIRED] The root d
irectory of the Skia source code.") | 32 skiaRoot = flag.String("skia_root", "", "[REQUIRED] The root d
irectory of the Skia source code.") |
| 33 clangPath = flag.String("clang_path", "", "[REQUIRED] The path
to the clang executable.") | 33 clangPath = flag.String("clang_path", "", "[REQUIRED] The path
to the clang executable.") |
| 34 clangPlusPlusPath = flag.String("clang_p_p_path", "", "[REQUIRED] The p
ath to the clang++ executable.") | 34 clangPlusPlusPath = flag.String("clang_p_p_path", "", "[REQUIRED] The p
ath to the clang++ executable.") |
| 35 depotToolsPath = flag.String("depot_tools_path", "", "The absolute p
ath to depot_tools. Can be empty if they are on your path.") | 35 depotToolsPath = flag.String("depot_tools_path", "", "The absolute p
ath to depot_tools. Can be empty if they are on your path.") |
| 36 aflRoot = flag.String("afl_root", "", "[REQUIRED] The install
directory of afl-fuzz (v1.94b or later).") | 36 aflRoot = flag.String("afl_root", "", "[REQUIRED] The install
directory of afl-fuzz (v1.94b or later).") |
| 37 numFuzzProcesses = flag.Int("fuzz_processes", 0, `The number of proces
ses to run afl-fuzz [per fuzz to run]. This should be fewer than the number of
logical cores. Defaults to 0, which means "Make an intelligent guess"`) | 37 numFuzzProcesses = flag.Int("fuzz_processes", 0, `The number of proces
ses to run afl-fuzz [per fuzz to run]. This should be fewer than the number of
logical cores. Defaults to 0, which means "Make an intelligent guess"`) |
| 38 watchAFL = flag.Bool("watch_afl", false, "(debug only) If the
afl master's output should be piped to stdout.") | |
| 39 versionCheckPeriod = flag.Duration("version_check_period", 20*time.Secon
d, `The period used to check the version of Skia that needs fuzzing.`) | 38 versionCheckPeriod = flag.Duration("version_check_period", 20*time.Secon
d, `The period used to check the version of Skia that needs fuzzing.`) |
| 40 downloadProcesses = flag.Int("download_processes", 4, "The number of do
wnload processes to be used for fetching fuzzes when re-analyzing them. This is
constant with respect to the number of fuzzes.") | 39 downloadProcesses = flag.Int("download_processes", 4, "The number of do
wnload processes to be used for fetching fuzzes when re-analyzing them. This is
constant with respect to the number of fuzzes.") |
| 41 fuzzesToRun = common.NewMultiStringFlag("fuzz_to_run", nil, fmt.S
printf("A set of fuzzes to run. Can be one or more of the known fuzzes: %q", fc
ommon.FUZZ_CATEGORIES)) | 40 fuzzesToRun = common.NewMultiStringFlag("fuzz_to_run", nil, fmt.S
printf("A set of fuzzes to run. Can be one or more of the known fuzzes: %q", fc
ommon.FUZZ_CATEGORIES)) |
| 42 | 41 |
| 43 bucket = flag.String("bucket", "skia-fuzzer", "The GCS buc
ket in which to store found fuzzes.") | 42 bucket = flag.String("bucket", "skia-fuzzer", "The GCS buc
ket in which to store found fuzzes.") |
| 44 fuzzPath = flag.String("fuzz_path", filepath.Join(os.TempDir
(), "fuzzes"), "The directory to temporarily store the binary fuzzes during aggr
egation.") | 43 fuzzPath = flag.String("fuzz_path", filepath.Join(os.TempDir
(), "fuzzes"), "The directory to temporarily store the binary fuzzes during aggr
egation.") |
| 45 executablePath = flag.String("executable_path", filepath.Join(os.T
empDir(), "executables"), "The directory to store temporary executables that wil
l run the fuzzes during aggregation. Defaults to /tmp/executables.") | 44 executablePath = flag.String("executable_path", filepath.Join(os.T
empDir(), "executables"), "The directory to store temporary executables that wil
l run the fuzzes during aggregation. Defaults to /tmp/executables.") |
| 46 numAnalysisProcesses = flag.Int("analysis_processes", 0, `The number of
processes to analyze fuzzes [per fuzz to run]. This should be fewer than the nu
mber of logical cores. Defaults to 0, which means "Make an intelligent guess"`) | 45 numAnalysisProcesses = flag.Int("analysis_processes", 0, `The number of
processes to analyze fuzzes [per fuzz to run]. This should be fewer than the nu
mber of logical cores. Defaults to 0, which means "Make an intelligent guess"`) |
| 47 rescanPeriod = flag.Duration("rescan_period", 60*time.Second, `T
he time in which to sleep for every cycle of aggregation. `) | 46 rescanPeriod = flag.Duration("rescan_period", 60*time.Second, `T
he time in which to sleep for every cycle of aggregation. `) |
| 48 numUploadProcesses = flag.Int("upload_processes", 0, `The number of pr
ocesses to upload fuzzes [per fuzz to run]. Defaults to 0, which means "Make an
intelligent guess"`) | 47 numUploadProcesses = flag.Int("upload_processes", 0, `The number of pr
ocesses to upload fuzzes [per fuzz to run]. Defaults to 0, which means "Make an
intelligent guess"`) |
| 49 statusPeriod = flag.Duration("status_period", 60*time.Second, `T
he time period used to report the status of the aggregation/analysis/upload queu
e. `) | 48 statusPeriod = flag.Duration("status_period", 60*time.Second, `T
he time period used to report the status of the aggregation/analysis/upload queu
e. `) |
| 50 analysisTimeout = flag.Duration("analysis_timeout", 5*time.Second,
`The maximum time an analysis should run.`) | 49 analysisTimeout = flag.Duration("analysis_timeout", 5*time.Second,
`The maximum time an analysis should run.`) |
| 51 | 50 |
| 52 graphiteServer = flag.String("graphite_server", "localhost:2003", "Where
is Graphite metrics ingestion server running.") | 51 graphiteServer = flag.String("graphite_server", "localhost:2003", "Where
is Graphite metrics ingestion server running.") |
| 52 |
| 53 watchAFL = flag.Bool("watch_afl", false, "(debug only) If the afl
master's output should be piped to stdout.") |
| 54 skipGeneration = flag.Bool("skip_generation", false, "(debug only) If t
he generation step should be disabled.") |
| 55 forceReanalysis = flag.Bool("force_reanalysis", false, "(debug only) If
the fuzzes should be downloaded, re-analyzed, (deleted for GCS), and reuploaded.
") |
| 56 verboseBuilds = flag.Bool("verbose_builds", false, "If output from nin
ja and gyp should be printed to stdout.") |
| 53 ) | 57 ) |
| 54 | 58 |
| 55 var ( | 59 var ( |
| 56 requiredFlags = []string{"afl_output_path", "skia_root",
"clang_path", "clang_p_p_path", "afl_root", "generator_working_dir", "fuzz_to_r
un"} | 60 requiredFlags = []string{"afl_output_path", "skia_root",
"clang_path", "clang_p_p_path", "afl_root", "generator_working_dir", "fuzz_to_r
un"} |
| 57 storageClient *storage.Client = nil | 61 storageClient *storage.Client = nil |
| 58 ) | 62 ) |
| 59 | 63 |
| 60 func main() { | 64 func main() { |
| 61 defer common.LogPanic() | 65 defer common.LogPanic() |
| 62 // Calls flag.Parse() | 66 // Calls flag.Parse() |
| (...skipping 10 matching lines...) Expand all Loading... |
| 73 } | 77 } |
| 74 | 78 |
| 75 fuzzPipelines := make([]backend.FuzzPipeline, 0, len(*fuzzesToRun)) | 79 fuzzPipelines := make([]backend.FuzzPipeline, 0, len(*fuzzesToRun)) |
| 76 | 80 |
| 77 for _, category := range *fuzzesToRun { | 81 for _, category := range *fuzzesToRun { |
| 78 gen := generator.New(category) | 82 gen := generator.New(category) |
| 79 if err := gen.DownloadSeedFiles(storageClient); err != nil { | 83 if err := gen.DownloadSeedFiles(storageClient); err != nil { |
| 80 glog.Fatalf("Problem downloading binary seed files: %s",
err) | 84 glog.Fatalf("Problem downloading binary seed files: %s",
err) |
| 81 } | 85 } |
| 82 | 86 |
| 83 » » glog.Infof("Starting %s generator with configuration %#v", categ
ory, config.Generator) | 87 » » // If we are reanalyzing, no point in running the generator firs
t, just to stop it. |
| 84 » » if err := gen.Start(); err != nil { | 88 » » if !*skipGeneration && !*forceReanalysis { |
| 85 » » » glog.Fatalf("Problem starting binary generator: %s", err
) | 89 » » » glog.Infof("Starting %s generator with configuration %#v
", category, config.Generator) |
| 90 » » » if err := gen.Start(); err != nil { |
| 91 » » » » glog.Fatalf("Problem starting binary generator:
%s", err) |
| 92 » » » } |
| 93 » » } else { |
| 94 » » » glog.Infof("Skipping %s generator because --skip_generat
ion is enabled", category) |
| 86 } | 95 } |
| 87 | 96 |
| 88 glog.Infof("Starting %s aggregator with configuration %#v", cate
gory, config.Aggregator) | 97 glog.Infof("Starting %s aggregator with configuration %#v", cate
gory, config.Aggregator) |
| 89 agg, err := aggregator.StartAggregator(storageClient, category) | 98 agg, err := aggregator.StartAggregator(storageClient, category) |
| 90 if err != nil { | 99 if err != nil { |
| 91 glog.Fatalf("Could not start aggregator: %s", err) | 100 glog.Fatalf("Could not start aggregator: %s", err) |
| 92 } | 101 } |
| 93 fuzzPipelines = append(fuzzPipelines, backend.FuzzPipeline{ | 102 fuzzPipelines = append(fuzzPipelines, backend.FuzzPipeline{ |
| 94 Category: category, | 103 Category: category, |
| 95 Agg: agg, | 104 Agg: agg, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 } | 137 } |
| 129 config.Generator.WorkingPath, err = fileutil.EnsureDirExists(*generatorW
D) | 138 config.Generator.WorkingPath, err = fileutil.EnsureDirExists(*generatorW
D) |
| 130 if err != nil { | 139 if err != nil { |
| 131 return err | 140 return err |
| 132 } | 141 } |
| 133 config.Generator.FuzzSamples, err = fileutil.EnsureDirExists(*fuzzSample
s) | 142 config.Generator.FuzzSamples, err = fileutil.EnsureDirExists(*fuzzSample
s) |
| 134 if err != nil { | 143 if err != nil { |
| 135 return err | 144 return err |
| 136 } | 145 } |
| 137 | 146 |
| 147 config.Common.VerboseBuilds = *verboseBuilds |
| 138 config.Common.ClangPath = *clangPath | 148 config.Common.ClangPath = *clangPath |
| 139 config.Common.ClangPlusPlusPath = *clangPlusPlusPath | 149 config.Common.ClangPlusPlusPath = *clangPlusPlusPath |
| 140 config.Common.DepotToolsPath = *depotToolsPath | 150 config.Common.DepotToolsPath = *depotToolsPath |
| 141 config.Generator.NumFuzzProcesses = *numFuzzProcesses | 151 config.Generator.NumFuzzProcesses = *numFuzzProcesses |
| 142 config.Generator.WatchAFL = *watchAFL | 152 config.Generator.WatchAFL = *watchAFL |
| 143 config.Generator.VersionCheckPeriod = *versionCheckPeriod | 153 config.Generator.VersionCheckPeriod = *versionCheckPeriod |
| 144 config.Generator.NumDownloadProcesses = *downloadProcesses | 154 config.Generator.NumDownloadProcesses = *downloadProcesses |
| 145 | 155 |
| 146 config.GS.Bucket = *bucket | 156 config.GS.Bucket = *bucket |
| 147 config.Aggregator.FuzzPath, err = fileutil.EnsureDirExists(*fuzzPath) | 157 config.Aggregator.FuzzPath, err = fileutil.EnsureDirExists(*fuzzPath) |
| 148 if err != nil { | 158 if err != nil { |
| 149 return err | 159 return err |
| 150 } | 160 } |
| 151 config.Aggregator.ExecutablePath, err = fileutil.EnsureDirExists(*execut
ablePath) | 161 config.Aggregator.ExecutablePath, err = fileutil.EnsureDirExists(*execut
ablePath) |
| 152 if err != nil { | 162 if err != nil { |
| 153 return err | 163 return err |
| 154 } | 164 } |
| 155 config.Aggregator.NumAnalysisProcesses = *numAnalysisProcesses | 165 config.Aggregator.NumAnalysisProcesses = *numAnalysisProcesses |
| 156 config.Aggregator.NumUploadProcesses = *numUploadProcesses | 166 config.Aggregator.NumUploadProcesses = *numUploadProcesses |
| 157 config.Aggregator.StatusPeriod = *statusPeriod | 167 config.Aggregator.StatusPeriod = *statusPeriod |
| 158 config.Aggregator.RescanPeriod = *rescanPeriod | 168 config.Aggregator.RescanPeriod = *rescanPeriod |
| 159 config.Aggregator.AnalysisTimeout = *analysisTimeout | 169 config.Aggregator.AnalysisTimeout = *analysisTimeout |
| 170 config.Common.ForceReanalysis = *forceReanalysis |
| 160 | 171 |
| 161 // Check all the fuzzes are valid ones we can handle | 172 // Check all the fuzzes are valid ones we can handle |
| 162 for _, f := range *fuzzesToRun { | 173 for _, f := range *fuzzesToRun { |
| 163 if !fcommon.HasCategory(f) { | 174 if !fcommon.HasCategory(f) { |
| 164 return fmt.Errorf("Unknown fuzz category %q", f) | 175 return fmt.Errorf("Unknown fuzz category %q", f) |
| 165 } | 176 } |
| 166 } | 177 } |
| 167 return nil | 178 return nil |
| 168 } | 179 } |
| 169 | 180 |
| 170 func setupOAuth() error { | 181 func setupOAuth() error { |
| 171 client, err := auth.NewDefaultJWTServiceAccountClient(auth.SCOPE_READ_WR
ITE) | 182 client, err := auth.NewDefaultJWTServiceAccountClient(auth.SCOPE_READ_WR
ITE) |
| 172 if err != nil { | 183 if err != nil { |
| 173 return fmt.Errorf("Problem setting up client OAuth: %v", err) | 184 return fmt.Errorf("Problem setting up client OAuth: %v", err) |
| 174 } | 185 } |
| 175 | 186 |
| 176 if storageClient, err = storage.NewClient(context.Background(), cloud.Wi
thBaseHTTP(client)); err != nil { | 187 if storageClient, err = storage.NewClient(context.Background(), cloud.Wi
thBaseHTTP(client)); err != nil { |
| 177 return fmt.Errorf("Problem authenticating: %v", err) | 188 return fmt.Errorf("Problem authenticating: %v", err) |
| 178 } | 189 } |
| 179 return nil | 190 return nil |
| 180 } | 191 } |
| OLD | NEW |