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 |