blob: 79d2412798a4d0a7979ba7878758b7906e804d6a [file] [log] [blame]
hamzeh41ad8812021-07-07 14:00:07 -07001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
hamzehc0a671f2021-07-22 12:05:08 -070015package fuzz
hamzeh41ad8812021-07-07 14:00:07 -070016
17// This file contains the common code for compiling C/C++ and Rust fuzzers for Android.
18
19import (
hamzehc0a671f2021-07-22 12:05:08 -070020 "encoding/json"
hamzehe8a1bfa2022-06-21 12:22:06 -070021 "fmt"
hamzeh41ad8812021-07-07 14:00:07 -070022 "sort"
23 "strings"
24
hamzehc0a671f2021-07-22 12:05:08 -070025 "github.com/google/blueprint/proptools"
26
hamzeh41ad8812021-07-07 14:00:07 -070027 "android/soong/android"
28)
29
Cory Barker9cfcf6d2022-07-22 17:22:02 +000030type Lang string
hamzeh41ad8812021-07-07 14:00:07 -070031
32const (
Cory Barker9cfcf6d2022-07-22 17:22:02 +000033 Cc Lang = "cc"
34 Rust Lang = "rust"
35 Java Lang = "java"
36)
37
38type Framework string
39
40const (
41 AFL Framework = "afl"
42 LibFuzzer Framework = "libfuzzer"
43 Jazzer Framework = "jazzer"
44 UnknownFramework Framework = "unknownframework"
hamzeh41ad8812021-07-07 14:00:07 -070045)
46
hamzehc0a671f2021-07-22 12:05:08 -070047var BoolDefault = proptools.BoolDefault
48
hamzeh41ad8812021-07-07 14:00:07 -070049type FuzzModule struct {
50 android.ModuleBase
51 android.DefaultableModuleBase
52 android.ApexModuleBase
53}
54
55type FuzzPackager struct {
Ivan Lozano39b0bf02021-10-14 12:22:09 -040056 Packages android.Paths
57 FuzzTargets map[string]bool
58 SharedLibInstallStrings []string
hamzeh41ad8812021-07-07 14:00:07 -070059}
60
61type FileToZip struct {
62 SourceFilePath android.Path
63 DestinationPathPrefix string
64}
65
66type ArchOs struct {
67 HostOrTarget string
68 Arch string
69 Dir string
70}
71
hamzeheea256b2023-02-09 13:22:09 -080072type Vector string
hamzehe8a1bfa2022-06-21 12:22:06 -070073
74const (
hamzeheea256b2023-02-09 13:22:09 -080075 unknown_access_vector Vector = "unknown_access_vector"
76 // The code being fuzzed is reachable from a remote source, or using data
77 // provided by a remote source. For example: media codecs process media files
78 // from the internet, SMS processing handles remote message data.
79 // See
80 // https://source.android.com/docs/security/overview/updates-resources#local-vs-remote
81 // for an explanation of what's considered "remote."
82 remote = "remote"
83 // The code being fuzzed can only be reached locally, such as from an
84 // installed app. As an example, if it's fuzzing a Binder interface, it's
85 // assumed that you'd need a local app to make arbitrary Binder calls.
86 // And the app that's calling the fuzzed code does not require any privileges;
87 // any 3rd party app could make these calls.
88 local_no_privileges_required = "local_no_privileges_required"
89 // The code being fuzzed can only be called locally, and the calling process
90 // requires additional permissions that prevent arbitrary 3rd party apps from
91 // calling the code. For instance: this requires a privileged or signature
92 // permission to reach, or SELinux restrictions prevent the untrusted_app
93 // domain from calling it.
94 local_privileges_required = "local_privileges_required"
95 // The code is only callable on a PC host, not on a production Android device.
96 // For instance, this is fuzzing code used during the build process, or
97 // tooling that does not exist on a user's actual Android device.
98 host_access = "host_access"
99 // The code being fuzzed is only reachable if the user has enabled Developer
100 // Options, or has enabled a persistent Developer Options setting.
101 local_with_developer_options = "local_with_developer_options"
hamzehe8a1bfa2022-06-21 12:22:06 -0700102)
103
hamzeheea256b2023-02-09 13:22:09 -0800104func (vector Vector) isValidVector() bool {
105 switch vector {
106 case "",
107 unknown_access_vector,
108 remote,
109 local_no_privileges_required,
110 local_privileges_required,
111 host_access,
112 local_with_developer_options:
113 return true
114 }
115 return false
116}
117
118type ServicePrivilege string
119
120const (
121 unknown_service_privilege ServicePrivilege = "unknown_service_privilege"
122 // The code being fuzzed runs on a Secure Element. This has access to some
123 // of the most privileged data on the device, such as authentication keys.
124 // Not all devices have a Secure Element.
125 secure_element = "secure_element"
126 // The code being fuzzed runs in the TEE. The TEE is designed to be resistant
127 // to a compromised kernel, and stores sensitive data.
128 trusted_execution = "trusted_execution"
129 // The code being fuzzed has privileges beyond what arbitrary 3rd party apps
130 // have. For instance, it's running as the System UID, or it's in an SELinux
131 // domain that's able to perform calls that can't be made by 3rd party apps.
132 privileged = "privileged"
133 // The code being fuzzed is equivalent to a 3rd party app. It runs in the
134 // untrusted_app SELinux domain, or it only has privileges that are equivalent
135 // to what a 3rd party app could have.
136 unprivileged = "unprivileged"
137 // The code being fuzzed is significantly constrained, and even if it's
138 // compromised, it has significant restrictions that prevent it from
139 // performing most actions. This is significantly more restricted than
140 // UNPRIVILEGED. An example is the isolatedProcess=true setting in a 3rd
141 // party app. Or a process that's very restricted by SELinux, such as
142 // anything in the mediacodec SELinux domain.
143 constrained = "constrained"
144 // The code being fuzzed always has Negligible Security Impact. Even
145 // arbitrary out of bounds writes and full code execution would not be
146 // considered a security vulnerability. This typically only makes sense if
147 // FuzzedCodeUsage is set to FUTURE_VERSION or EXPERIMENTAL, and if
148 // AutomaticallyRouteTo is set to ALWAYS_NSI.
149 nsi = "nsi"
150 // The code being fuzzed only runs on a PC host, not on a production Android
151 // device. For instance, the fuzzer is fuzzing code used during the build
152 // process, or tooling that does not exist on a user's actual Android device.
153 host_only = "host_only"
154)
155
156func (service_privilege ServicePrivilege) isValidServicePrivilege() bool {
157 switch service_privilege {
158 case "",
159 unknown_service_privilege,
160 secure_element,
161 trusted_execution,
162 privileged,
163 unprivileged,
164 constrained,
165 nsi,
166 host_only:
167 return true
168 }
169 return false
170}
171
172type UserData string
173
174const (
175 unknown_user_data UserData = "unknown_user_data"
176 // The process being fuzzed only handles data from a single user, or from a
177 // single process or app. It's possible the process shuts down before
178 // handling data from another user/process/app, or it's possible the process
179 // only ever handles one user's/process's/app's data. As an example, some
180 // print spooler processes are started for a single document and terminate
181 // when done, so each instance only handles data from a single user/app.
182 single_user = "single_user"
183 // The process handles data from multiple users, or from multiple other apps
184 // or processes. Media processes, for instance, can handle media requests
185 // from multiple different apps without restarting. Wi-Fi and network
186 // processes handle data from multiple users, and processes, and apps.
187 multi_user = "multi_user"
188)
189
190func (user_data UserData) isValidUserData() bool {
191 switch user_data {
192 case "",
193 unknown_user_data,
194 single_user,
195 multi_user:
196 return true
197 }
198 return false
199}
200
201type FuzzedCodeUsage string
202
203const (
204 undefined FuzzedCodeUsage = "undefined"
205 unknown = "unknown"
206 // The code being fuzzed exists in a shipped version of Android and runs on
207 // devices in production.
208 shipped = "shipped"
209 // The code being fuzzed is not yet in a shipping version of Android, but it
210 // will be at some point in the future.
211 future_version = "future_version"
212 // The code being fuzzed is not in a shipping version of Android, and there
213 // are no plans to ship it in the future.
214 experimental = "experimental"
215)
216
217func (fuzzed_code_usage FuzzedCodeUsage) isValidFuzzedCodeUsage() bool {
218 switch fuzzed_code_usage {
219 case "",
220 undefined,
221 unknown,
222 shipped,
223 future_version,
224 experimental:
225 return true
226 }
227 return false
228}
229
230type AutomaticallyRouteTo string
231
232const (
233 undefined_routing AutomaticallyRouteTo = "undefined_routing"
234 // Automatically route this to the Android Automotive security team for
235 // assessment.
236 android_automotive = "android_automotive"
237 // This should not be used in fuzzer configurations. It is used internally
238 // by Severity Assigner to flag memory leak reports.
239 memory_leak = "memory_leak"
240 // Route this vulnerability to our Ittiam vendor team for assessment.
241 ittiam = "ittiam"
242 // Reports from this fuzzer are always NSI (see the NSI ServicePrivilegeEnum
243 // value for additional context). It is not possible for this code to ever
244 // have a security vulnerability.
245 always_nsi = "always_nsi"
246 // Route this vulnerability to AIDL team for assessment.
247 aidl = "aidl"
248)
249
250func (automatically_route_to AutomaticallyRouteTo) isValidAutomaticallyRouteTo() bool {
251 switch automatically_route_to {
252 case "",
253 undefined_routing,
254 android_automotive,
255 memory_leak,
256 ittiam,
257 always_nsi,
258 aidl:
259 return true
260 }
261 return false
262}
263
hamzehe8a1bfa2022-06-21 12:22:06 -0700264func IsValidConfig(fuzzModule FuzzPackagedModule, moduleName string) bool {
265 var config = fuzzModule.FuzzProperties.Fuzz_config
266 if config != nil {
hamzeheea256b2023-02-09 13:22:09 -0800267 if !config.Vector.isValidVector() {
268 panic(fmt.Errorf("Invalid vector in fuzz config in %s", moduleName))
hamzehe8a1bfa2022-06-21 12:22:06 -0700269 }
hamzeheea256b2023-02-09 13:22:09 -0800270
271 if !config.Service_privilege.isValidServicePrivilege() {
272 panic(fmt.Errorf("Invalid service_privilege in fuzz config in %s", moduleName))
273 }
274
275 if !config.Users.isValidUserData() {
276 panic(fmt.Errorf("Invalid users (user_data) in fuzz config in %s", moduleName))
277 }
278
279 if !config.Fuzzed_code_usage.isValidFuzzedCodeUsage() {
280 panic(fmt.Errorf("Invalid fuzzed_code_usage in fuzz config in %s", moduleName))
281 }
282
283 if !config.Automatically_route_to.isValidAutomaticallyRouteTo() {
284 panic(fmt.Errorf("Invalid automatically_route_to in fuzz config in %s", moduleName))
285 }
hamzehe8a1bfa2022-06-21 12:22:06 -0700286 }
hamzeheea256b2023-02-09 13:22:09 -0800287 return true
hamzehe8a1bfa2022-06-21 12:22:06 -0700288}
289
hamzehc0a671f2021-07-22 12:05:08 -0700290type FuzzConfig struct {
291 // Email address of people to CC on bugs or contact about this fuzz target.
292 Cc []string `json:"cc,omitempty"`
hamzehe8a1bfa2022-06-21 12:22:06 -0700293 // A brief description of what the fuzzed code does.
294 Description string `json:"description,omitempty"`
hamzeheea256b2023-02-09 13:22:09 -0800295 // Whether the code being fuzzed is remotely accessible or requires privileges
296 // to access locally.
297 Vector Vector `json:"vector,omitempty"`
298 // How privileged the service being fuzzed is.
299 Service_privilege ServicePrivilege `json:"service_privilege,omitempty"`
300 // Whether the service being fuzzed handles data from multiple users or only
301 // a single one.
302 Users UserData `json:"users,omitempty"`
303 // Specifies the use state of the code being fuzzed. This state factors into
304 // how an issue is handled.
305 Fuzzed_code_usage FuzzedCodeUsage `json:"fuzzed_code_usage,omitempty"`
306 // Comment describing how we came to these settings for this fuzzer.
307 Config_comment string
308 // Which team to route this to, if it should be routed automatically.
309 Automatically_route_to AutomaticallyRouteTo `json:"automatically_route_to,omitempty"`
hamzehe8a1bfa2022-06-21 12:22:06 -0700310 // Can third party/untrusted apps supply data to fuzzed code.
hamzeh3c983d22022-07-26 14:19:22 -0700311 Untrusted_data *bool `json:"untrusted_data,omitempty"`
Jon Bottarinia0b44cb2022-10-19 03:13:14 +0000312 // When code was released or will be released.
hamzehe8a1bfa2022-06-21 12:22:06 -0700313 Production_date string `json:"production_date,omitempty"`
314 // Prevents critical service functionality like phone calls, bluetooth, etc.
hamzeh3c983d22022-07-26 14:19:22 -0700315 Critical *bool `json:"critical,omitempty"`
hamzehc0a671f2021-07-22 12:05:08 -0700316 // Specify whether to enable continuous fuzzing on devices. Defaults to true.
317 Fuzz_on_haiku_device *bool `json:"fuzz_on_haiku_device,omitempty"`
318 // Specify whether to enable continuous fuzzing on host. Defaults to true.
319 Fuzz_on_haiku_host *bool `json:"fuzz_on_haiku_host,omitempty"`
320 // Component in Google's bug tracking system that bugs should be filed to.
321 Componentid *int64 `json:"componentid,omitempty"`
Jon Bottarinia0b44cb2022-10-19 03:13:14 +0000322 // Hotlist(s) in Google's bug tracking system that bugs should be marked with.
hamzehc0a671f2021-07-22 12:05:08 -0700323 Hotlists []string `json:"hotlists,omitempty"`
324 // Specify whether this fuzz target was submitted by a researcher. Defaults
325 // to false.
326 Researcher_submitted *bool `json:"researcher_submitted,omitempty"`
327 // Specify who should be acknowledged for CVEs in the Android Security
328 // Bulletin.
329 Acknowledgement []string `json:"acknowledgement,omitempty"`
330 // Additional options to be passed to libfuzzer when run in Haiku.
331 Libfuzzer_options []string `json:"libfuzzer_options,omitempty"`
332 // Additional options to be passed to HWASAN when running on-device in Haiku.
333 Hwasan_options []string `json:"hwasan_options,omitempty"`
334 // Additional options to be passed to HWASAN when running on host in Haiku.
335 Asan_options []string `json:"asan_options,omitempty"`
Muhammad Haseeb Ahmad7e744052022-03-25 22:50:53 +0000336 // If there's a Java fuzzer with JNI, a different version of Jazzer would
337 // need to be added to the fuzzer package than one without JNI
338 IsJni *bool `json:"is_jni,omitempty"`
Mark74c0ad22022-09-30 21:13:01 +0000339 // List of modules for monitoring coverage drops in directories (e.g. "libicu")
340 Target_modules []string `json:"target_modules,omitempty"`
David Fuaf4e33b2023-04-07 12:24:35 -0700341 // Specifies a bug assignee to replace default ISE assignment
342 Assignee string `json:"assignee,omitempty"`
hamzehc0a671f2021-07-22 12:05:08 -0700343}
344
Cory Barker9cfcf6d2022-07-22 17:22:02 +0000345type FuzzFrameworks struct {
346 Afl *bool
347 Libfuzzer *bool
348 Jazzer *bool
349}
350
hamzehc0a671f2021-07-22 12:05:08 -0700351type FuzzProperties struct {
352 // Optional list of seed files to be installed to the fuzz target's output
353 // directory.
354 Corpus []string `android:"path"`
355 // Optional list of data files to be installed to the fuzz target's output
356 // directory. Directory structure relative to the module is preserved.
357 Data []string `android:"path"`
358 // Optional dictionary to be installed to the fuzz target's output directory.
359 Dictionary *string `android:"path"`
Cory Barker9cfcf6d2022-07-22 17:22:02 +0000360 // Define the fuzzing frameworks this fuzz target can be built for. If
361 // empty then the fuzz target will be available to be built for all fuzz
362 // frameworks available
363 Fuzzing_frameworks *FuzzFrameworks
hamzehc0a671f2021-07-22 12:05:08 -0700364 // Config for running the target on fuzzing infrastructure.
365 Fuzz_config *FuzzConfig
366}
367
hamzeh41ad8812021-07-07 14:00:07 -0700368type FuzzPackagedModule struct {
369 FuzzProperties FuzzProperties
370 Dictionary android.Path
371 Corpus android.Paths
372 CorpusIntermediateDir android.Path
373 Config android.Path
374 Data android.Paths
375 DataIntermediateDir android.Path
376}
377
Cory Barker9cfcf6d2022-07-22 17:22:02 +0000378func GetFramework(ctx android.LoadHookContext, lang Lang) Framework {
379 framework := ctx.Config().Getenv("FUZZ_FRAMEWORK")
380
381 if lang == Cc {
382 switch strings.ToLower(framework) {
383 case "":
384 return LibFuzzer
385 case "libfuzzer":
386 return LibFuzzer
387 case "afl":
388 return AFL
389 }
390 } else if lang == Rust {
391 return LibFuzzer
392 } else if lang == Java {
393 return Jazzer
394 }
395
396 ctx.ModuleErrorf(fmt.Sprintf("%s is not a valid fuzzing framework for %s", framework, lang))
397 return UnknownFramework
398}
399
400func IsValidFrameworkForModule(targetFramework Framework, lang Lang, moduleFrameworks *FuzzFrameworks) bool {
401 if targetFramework == UnknownFramework {
402 return false
403 }
404
405 if moduleFrameworks == nil {
406 return true
407 }
408
409 switch targetFramework {
410 case LibFuzzer:
411 return proptools.BoolDefault(moduleFrameworks.Libfuzzer, true)
412 case AFL:
413 return proptools.BoolDefault(moduleFrameworks.Afl, true)
414 case Jazzer:
415 return proptools.BoolDefault(moduleFrameworks.Jazzer, true)
416 default:
417 panic("%s is not supported as a fuzz framework")
418 }
419}
420
hamzeh41ad8812021-07-07 14:00:07 -0700421func IsValid(fuzzModule FuzzModule) bool {
422 // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
423 // fuzz targets we're going to package anyway.
424 if !fuzzModule.Enabled() || fuzzModule.InRamdisk() || fuzzModule.InVendorRamdisk() || fuzzModule.InRecovery() {
425 return false
426 }
427
428 // Discard modules that are in an unavailable namespace.
429 if !fuzzModule.ExportedToMake() {
430 return false
431 }
432
433 return true
434}
435
436func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip {
437 // Package the corpora into a zipfile.
438 var files []FileToZip
439 if fuzzModule.Corpus != nil {
440 corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip")
441 command := builder.Command().BuiltTool("soong_zip").
442 Flag("-j").
443 FlagWithOutput("-o ", corpusZip)
444 rspFile := corpusZip.ReplaceExtension(ctx, "rsp")
445 command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.Corpus)
446 files = append(files, FileToZip{corpusZip, ""})
447 }
448
449 // Package the data into a zipfile.
450 if fuzzModule.Data != nil {
451 dataZip := archDir.Join(ctx, module.Name()+"_data.zip")
452 command := builder.Command().BuiltTool("soong_zip").
453 FlagWithOutput("-o ", dataZip)
454 for _, f := range fuzzModule.Data {
455 intermediateDir := strings.TrimSuffix(f.String(), f.Rel())
456 command.FlagWithArg("-C ", intermediateDir)
457 command.FlagWithInput("-f ", f)
458 }
459 files = append(files, FileToZip{dataZip, ""})
460 }
461
462 // The dictionary.
463 if fuzzModule.Dictionary != nil {
464 files = append(files, FileToZip{fuzzModule.Dictionary, ""})
465 }
466
467 // Additional fuzz config.
hamzehe8a1bfa2022-06-21 12:22:06 -0700468 if fuzzModule.Config != nil && IsValidConfig(fuzzModule, module.Name()) {
hamzeh41ad8812021-07-07 14:00:07 -0700469 files = append(files, FileToZip{fuzzModule.Config, ""})
470 }
471
472 return files
473}
474
475func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) {
476 fuzzZip := archDir.Join(ctx, module.Name()+".zip")
477
478 command := builder.Command().BuiltTool("soong_zip").
479 Flag("-j").
480 FlagWithOutput("-o ", fuzzZip)
481
482 for _, file := range files {
483 if file.DestinationPathPrefix != "" {
484 command.FlagWithArg("-P ", file.DestinationPathPrefix)
485 } else {
486 command.Flag("-P ''")
487 }
488 command.FlagWithInput("-f ", file.SourceFilePath)
489 }
490
491 builder.Build("create-"+fuzzZip.String(),
492 "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
493
494 // Don't add modules to 'make haiku-rust' that are set to not be
495 // exported to the fuzzing infrastructure.
496 if config := fuzzModule.FuzzProperties.Fuzz_config; config != nil {
497 if strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_host, true) {
498 return archDirs[archOs], false
499 } else if !BoolDefault(config.Fuzz_on_haiku_device, true) {
500 return archDirs[archOs], false
501 }
502 }
503
504 s.FuzzTargets[module.Name()] = true
505 archDirs[archOs] = append(archDirs[archOs], FileToZip{fuzzZip, ""})
506
507 return archDirs[archOs], true
508}
509
hamzehc0a671f2021-07-22 12:05:08 -0700510func (f *FuzzConfig) String() string {
511 b, err := json.Marshal(f)
512 if err != nil {
513 panic(err)
514 }
515
516 return string(b)
517}
518
Cory Barker9cfcf6d2022-07-22 17:22:02 +0000519func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, fuzzType Lang, pctx android.PackageContext) {
hamzeh41ad8812021-07-07 14:00:07 -0700520 var archOsList []ArchOs
521 for archOs := range archDirs {
522 archOsList = append(archOsList, archOs)
523 }
524 sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].Dir < archOsList[j].Dir })
525
526 for _, archOs := range archOsList {
527 filesToZip := archDirs[archOs]
528 arch := archOs.Arch
529 hostOrTarget := archOs.HostOrTarget
530 builder := android.NewRuleBuilder(pctx, ctx)
531 zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip"
Cory Barkera1da26f2022-06-07 20:12:06 +0000532 if fuzzType == Rust {
hamzeh41ad8812021-07-07 14:00:07 -0700533 zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip"
534 }
Cory Barkera1da26f2022-06-07 20:12:06 +0000535 if fuzzType == Java {
Muhammad Haseeb Ahmade3803102022-01-10 21:37:07 +0000536 zipFileName = "fuzz-java-" + hostOrTarget + "-" + arch + ".zip"
537 }
Cory Barker9cfcf6d2022-07-22 17:22:02 +0000538
hamzeh41ad8812021-07-07 14:00:07 -0700539 outputFile := android.PathForOutput(ctx, zipFileName)
540
541 s.Packages = append(s.Packages, outputFile)
542
543 command := builder.Command().BuiltTool("soong_zip").
544 Flag("-j").
545 FlagWithOutput("-o ", outputFile).
546 Flag("-L 0") // No need to try and re-compress the zipfiles.
547
548 for _, fileToZip := range filesToZip {
hamzeh41ad8812021-07-07 14:00:07 -0700549 if fileToZip.DestinationPathPrefix != "" {
550 command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
551 } else {
552 command.Flag("-P ''")
553 }
554 command.FlagWithInput("-f ", fileToZip.SourceFilePath)
555
556 }
557 builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget,
558 "Create fuzz target packages for "+arch+"-"+hostOrTarget)
559 }
560}
561
562func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets string) {
563 fuzzTargets := make([]string, 0, len(s.FuzzTargets))
564 for target, _ := range s.FuzzTargets {
565 fuzzTargets = append(fuzzTargets, target)
566 }
Cory Barkera1da26f2022-06-07 20:12:06 +0000567
hamzeh41ad8812021-07-07 14:00:07 -0700568 sort.Strings(fuzzTargets)
569 ctx.Strict(targets, strings.Join(fuzzTargets, " "))
570}