Loading cc/cc.go +11 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,9 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel() ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel() ctx.TopDown("fuzz_deps", fuzzMutatorDeps) ctx.BottomUp("fuzz", fuzzMutator) ctx.BottomUp("coverage", coverageMutator).Parallel() ctx.TopDown("afdo_deps", afdoDepsMutator) Loading Loading @@ -838,6 +841,7 @@ type Module struct { stl *stl sanitize *sanitize coverage *coverage fuzzer *fuzzer sabi *sabi vndkdep *vndkdep lto *lto Loading Loading @@ -1163,6 +1167,9 @@ func (c *Module) Init() android.Module { if c.coverage != nil { c.AddProperties(c.coverage.props()...) } if c.fuzzer != nil { c.AddProperties(c.fuzzer.props()...) } if c.sabi != nil { c.AddProperties(c.sabi.props()...) } Loading Loading @@ -1680,6 +1687,7 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo module.stl = &stl{} module.sanitize = &sanitize{} module.coverage = &coverage{} module.fuzzer = &fuzzer{} module.sabi = &sabi{} module.vndkdep = &vndkdep{} module.lto = <o{} Loading Loading @@ -1901,6 +1909,9 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if c.coverage != nil { flags, deps = c.coverage.flags(ctx, flags, deps) } if c.fuzzer != nil { flags = c.fuzzer.flags(ctx, flags) } if c.lto != nil { flags = c.lto.flags(ctx, flags) } Loading cc/cc_test.go +119 −0 Original line number Diff line number Diff line Loading @@ -3342,6 +3342,125 @@ func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) { `) } func TestAFLFuzzTarget(t *testing.T) { ctx := testCc(t, ` cc_afl_fuzz { name: "test_afl_fuzz_target", srcs: ["foo.c"], host_supported: true, static_libs: [ "afl_fuzz_static_lib", ], shared_libs: [ "afl_fuzz_shared_lib", ], } cc_fuzz { name: "test_fuzz_target", srcs: ["foo.c"], static_libs: [ "afl_fuzz_static_lib", "libfuzzer_only_static_lib", ], shared_libs: [ "afl_fuzz_shared_lib", ], } cc_library { name: "afl_fuzz_static_lib", host_supported: true, srcs: ["static_file.c"], } cc_library { name: "libfuzzer_only_static_lib", host_supported: true, srcs: ["static_file.c"], } cc_library { name: "afl_fuzz_shared_lib", host_supported: true, srcs: ["shared_file.c"], static_libs: [ "second_static_lib", ], } cc_library_headers { name: "libafl_headers", vendor_available: true, host_supported: true, export_include_dirs: [ "include", "instrumentation", ], } cc_object { name: "afl-compiler-rt", vendor_available: true, host_supported: true, cflags: [ "-fPIC", ], srcs: [ "instrumentation/afl-compiler-rt.o.c", ], } cc_library { name: "second_static_lib", host_supported: true, srcs: ["second_file.c"], } filegroup { name: "aflpp_driver", srcs: [ "aflpp_driver.c", ], }`) checkPcGuardFlag := func( modName string, variantName string, shouldHave bool) { cc := ctx.ModuleForTests(modName, variantName).Rule("cc") cFlags, ok := cc.Args["cFlags"] if !ok { t.Errorf("Could not find cFlags for module %s and variant %s", modName, variantName) } if strings.Contains( cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave { t.Errorf("Flag was found: %t. Expected to find flag: %t. "+ "Test failed for module %s and variant %s", !shouldHave, shouldHave, modName, variantName) } } for _, vnt := range ctx.ModuleVariantsForTests("libfuzzer_only_static_lib") { if strings.Contains(vnt, "fuzzer_afl") { t.Errorf("libfuzzer_only_static_lib has afl variant and should not") } } moduleName := "test_afl_fuzz_target" variantName := "android_arm64_armv8-a_fuzzer_afl" checkPcGuardFlag(moduleName, variantName, true) moduleName = "afl_fuzz_static_lib" variantName = "android_arm64_armv8-a_static" checkPcGuardFlag(moduleName, variantName, false) checkPcGuardFlag(moduleName, variantName+"_fuzzer", false) checkPcGuardFlag(moduleName, variantName+"_fuzzer_afl", true) moduleName = "second_static_lib" checkPcGuardFlag(moduleName, variantName, false) checkPcGuardFlag(moduleName, variantName+"_fuzzer", false) checkPcGuardFlag(moduleName, variantName+"_fuzzer_afl", true) ctx.ModuleForTests("afl_fuzz_shared_lib", "android_arm64_armv8-a_shared").Rule("cc") ctx.ModuleForTests("afl_fuzz_shared_lib", "android_arm64_armv8-a_shared_fuzzer_afl").Rule("cc") } // Simple smoke test for the cc_fuzz target that ensures the rule compiles // correctly. func TestFuzzTarget(t *testing.T) { Loading cc/fuzz.go +210 −61 Original line number Diff line number Diff line Loading @@ -27,29 +27,113 @@ import ( ) func init() { android.RegisterModuleType("cc_fuzz", FuzzFactory) android.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory) android.RegisterModuleType("cc_fuzz", LibFuzzFactory) android.RegisterSingletonType("cc_fuzz_packaging", fuzzPackagingFactory) android.RegisterSingletonType("cc_afl_fuzz_packaging", fuzzAFLPackagingFactory) } type FuzzProperties struct { AFLEnabled bool `blueprint:"mutated"` AFLAddFlags bool `blueprint:"mutated"` } type fuzzer struct { Properties FuzzProperties } func (fuzzer *fuzzer) flags(ctx ModuleContext, flags Flags) Flags { if fuzzer.Properties.AFLAddFlags { flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-coverage=trace-pc-guard") } return flags } func (fuzzer *fuzzer) props() []interface{} { return []interface{}{&fuzzer.Properties} } func fuzzMutatorDeps(mctx android.TopDownMutatorContext) { currentModule, ok := mctx.Module().(*Module) if !ok { return } if currentModule.fuzzer == nil || !currentModule.fuzzer.Properties.AFLEnabled { return } mctx.WalkDeps(func(child android.Module, parent android.Module) bool { c, ok := child.(*Module) if !ok { return false } if c.sanitize == nil { return false } isFuzzerPointer := c.sanitize.getSanitizerBoolPtr(Fuzzer) if isFuzzerPointer == nil || !*isFuzzerPointer { return false } if c.fuzzer == nil { return false } c.fuzzer.Properties.AFLEnabled = true c.fuzzer.Properties.AFLAddFlags = true return true }) } func fuzzMutator(mctx android.BottomUpMutatorContext) { if c, ok := mctx.Module().(*Module); ok && c.fuzzer != nil { if !c.fuzzer.Properties.AFLEnabled { return } if c.Binary() { m := mctx.CreateVariations("afl") m[0].(*Module).fuzzer.Properties.AFLEnabled = true m[0].(*Module).fuzzer.Properties.AFLAddFlags = true } else { m := mctx.CreateVariations("", "afl") m[0].(*Module).fuzzer.Properties.AFLEnabled = false m[0].(*Module).fuzzer.Properties.AFLAddFlags = false m[1].(*Module).fuzzer.Properties.AFLEnabled = true m[1].(*Module).fuzzer.Properties.AFLAddFlags = true } } } // cc_fuzz creates a host/device fuzzer binary. Host binaries can be found at // $ANDROID_HOST_OUT/fuzz/, and device binaries can be found at /data/fuzz on // your device, or $ANDROID_PRODUCT_OUT/data/fuzz in your build tree. func FuzzFactory() android.Module { module := NewFuzz(android.HostAndDeviceSupported) func LibFuzzFactory() android.Module { module := NewFuzzer(android.HostAndDeviceSupported, fuzz.Cc) return module.Init() } func NewFuzzInstaller() *baseInstaller { return NewBaseInstaller("fuzz", "fuzz", InstallInData) // cc_afl_fuzz creates a host/device AFL++ fuzzer binary. // AFL++ is an open source framework used to fuzz libraries // Host binaries can be found at $ANDROID_HOST_OUT/afl_fuzz/ and device // binaries can be found at $ANDROID_PRODUCT_OUT/data/afl_fuzz in your // build tree func AFLFuzzFactory() android.Module { module := NewFuzzer(android.HostAndDeviceSupported, fuzz.AFL) return module.Init() } type fuzzBinary struct { *binaryDecorator *baseCompiler fuzzPackagedModule fuzz.FuzzPackagedModule installedSharedDeps []string fuzzType fuzz.FuzzType } func (fuzz *fuzzBinary) fuzzBinary() bool { Loading @@ -66,12 +150,18 @@ func (fuzz *fuzzBinary) linkerInit(ctx BaseModuleContext) { fuzz.binaryDecorator.linkerInit(ctx) } func (fuzz *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary(ctx.toolchain())) deps = fuzz.binaryDecorator.linkerDeps(ctx, deps) func (fuzzBin *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { if fuzzBin.fuzzType == fuzz.AFL { deps.HeaderLibs = append(deps.HeaderLibs, "libafl_headers") deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps) return deps } else { deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary(ctx.toolchain())) deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps) return deps } } func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags = fuzz.binaryDecorator.linkerFlags(ctx, flags) Loading @@ -80,6 +170,7 @@ func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { // target packages. flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`) flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/lib`) return flags } Loading Loading @@ -149,63 +240,68 @@ func IsValidSharedDependency(dependency android.Module) bool { } func sharedLibraryInstallLocation( libraryPath android.Path, isHost bool, archString string) string { libraryPath android.Path, isHost bool, fuzzDir string, archString string) string { installLocation := "$(PRODUCT_OUT)/data" if isHost { installLocation = "$(HOST_OUT)" } installLocation = filepath.Join( installLocation, "fuzz", archString, "lib", libraryPath.Base()) installLocation, fuzzDir, archString, "lib", libraryPath.Base()) return installLocation } // Get the device-only shared library symbols install directory. func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, archString string) string { return filepath.Join("$(PRODUCT_OUT)/symbols/data/fuzz/", archString, "/lib/", libraryPath.Base()) func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, fuzzDir string, archString string) string { return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, "/lib/", libraryPath.Base()) } func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { fuzz.binaryDecorator.baseInstaller.dir = filepath.Join( "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join( "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseInstaller.install(ctx, file) func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) { installBase := "fuzz" if fuzzBin.fuzzType == fuzz.AFL { installBase = "afl_fuzz" } fuzzBin.binaryDecorator.baseInstaller.dir = filepath.Join( installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzzBin.binaryDecorator.baseInstaller.dir64 = filepath.Join( installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzzBin.binaryDecorator.baseInstaller.install(ctx, file) fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus) fuzzBin.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Corpus) builder := android.NewRuleBuilder(pctx, ctx) intermediateDir := android.PathForModuleOut(ctx, "corpus") for _, entry := range fuzz.fuzzPackagedModule.Corpus { for _, entry := range fuzzBin.fuzzPackagedModule.Corpus { builder.Command().Text("cp"). Input(entry). Output(intermediateDir.Join(ctx, entry.Base())) } builder.Build("copy_corpus", "copy corpus") fuzz.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir fuzzBin.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data) fuzzBin.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Data) builder = android.NewRuleBuilder(pctx, ctx) intermediateDir = android.PathForModuleOut(ctx, "data") for _, entry := range fuzz.fuzzPackagedModule.Data { for _, entry := range fuzzBin.fuzzPackagedModule.Data { builder.Command().Text("cp"). Input(entry). Output(intermediateDir.Join(ctx, entry.Rel())) } builder.Build("copy_data", "copy data") fuzz.fuzzPackagedModule.DataIntermediateDir = intermediateDir fuzzBin.fuzzPackagedModule.DataIntermediateDir = intermediateDir if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil { fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary) if fuzz.fuzzPackagedModule.Dictionary.Ext() != ".dict" { if fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary != nil { fuzzBin.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary) if fuzzBin.fuzzPackagedModule.Dictionary.Ext() != ".dict" { ctx.PropertyErrorf("dictionary", "Fuzzer dictionary %q does not have '.dict' extension", fuzz.fuzzPackagedModule.Dictionary.String()) fuzzBin.fuzzPackagedModule.Dictionary.String()) } } if fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil { if fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil { configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json") android.WriteFileRule(ctx, configPath, fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config.String()) fuzz.fuzzPackagedModule.Config = configPath android.WriteFileRule(ctx, configPath, fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config.String()) fuzzBin.fuzzPackagedModule.Config = configPath } // Grab the list of required shared libraries. Loading @@ -225,31 +321,36 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { }) for _, lib := range sharedLibraries { fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps, sharedLibraryInstallLocation( lib, ctx.Host(), ctx.Arch().ArchType.String())) lib, ctx.Host(), installBase, ctx.Arch().ArchType.String())) // Also add the dependency on the shared library symbols dir. if !ctx.Host() { fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, sharedLibrarySymbolsInstallLocation(lib, ctx.Arch().ArchType.String())) fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps, sharedLibrarySymbolsInstallLocation(lib, installBase, ctx.Arch().ArchType.String())) } } } func NewFuzz(hod android.HostOrDeviceSupported) *Module { func NewFuzzer(hod android.HostOrDeviceSupported, fuzzType fuzz.FuzzType) *Module { module, binary := newBinary(hod, false) baseInstallerPath := "fuzz" if fuzzType == fuzz.AFL { baseInstallerPath = "afl_fuzz" } binary.baseInstaller = NewFuzzInstaller() binary.baseInstaller = NewBaseInstaller(baseInstallerPath, baseInstallerPath, InstallInData) module.sanitize.SetSanitizer(Fuzzer, true) fuzz := &fuzzBinary{ fuzzBin := &fuzzBinary{ binaryDecorator: binary, baseCompiler: NewBaseCompiler(), fuzzType: fuzzType, } module.compiler = fuzz module.linker = fuzz module.installer = fuzz module.compiler = fuzzBin module.linker = fuzzBin module.installer = fuzzBin // The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin. android.AddLoadHook(module, func(ctx android.LoadHookContext) { Loading @@ -268,6 +369,17 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module { ctx.AppendProperties(&disableDarwinAndLinuxBionic) }) if fuzzType == fuzz.AFL { // Add cc_objects to Srcs fuzzBin.baseCompiler.Properties.Srcs = append(fuzzBin.baseCompiler.Properties.Srcs, ":aflpp_driver", ":afl-compiler-rt") module.fuzzer.Properties.AFLEnabled = true module.compiler.appendCflags([]string{ "-Wno-unused-result", "-Wno-unused-parameter", "-Wno-unused-function", }) } return module } Loading @@ -275,10 +387,30 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module { // their architecture & target/host specific zip file. type ccFuzzPackager struct { fuzz.FuzzPackager fuzzPackagingArchModules string fuzzTargetSharedDepsInstallPairs string allFuzzTargetsName string } func fuzzPackagingFactory() android.Singleton { return &ccFuzzPackager{} fuzzPackager := &ccFuzzPackager{ fuzzPackagingArchModules: "SOONG_FUZZ_PACKAGING_ARCH_MODULES", fuzzTargetSharedDepsInstallPairs: "FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS", allFuzzTargetsName: "ALL_FUZZ_TARGETS", } fuzzPackager.FuzzType = fuzz.Cc return fuzzPackager } func fuzzAFLPackagingFactory() android.Singleton { fuzzPackager := &ccFuzzPackager{ fuzzPackagingArchModules: "SOONG_AFL_FUZZ_PACKAGING_ARCH_MODULES", fuzzTargetSharedDepsInstallPairs: "AFL_FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS", allFuzzTargetsName: "ALL_AFL_FUZZ_TARGETS", } fuzzPackager.FuzzType = fuzz.AFL return fuzzPackager } func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { Loading Loading @@ -306,8 +438,9 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { return } sharedLibsInstallDirPrefix := "lib" fuzzModule, ok := ccModule.compiler.(*fuzzBinary) if !ok { if !ok || fuzzModule.fuzzType != s.FuzzType { return } Loading @@ -316,8 +449,18 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { hostOrTargetString = "host" } fpm := fuzz.FuzzPackagedModule{} if ok { fpm = fuzzModule.fuzzPackagedModule } intermediatePath := "fuzz" if s.FuzzType == fuzz.AFL { intermediatePath = "afl_fuzz" } archString := ccModule.Arch().ArchType.String() archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString) archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString) archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()} // Grab the list of required shared libraries. Loading @@ -327,22 +470,21 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { builder := android.NewRuleBuilder(pctx, ctx) // Package the corpus, data, dict and config into a zipfile. files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder) files = s.PackageArtifacts(ctx, module, fpm, archDir, builder) // Package shared libraries files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...) files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...) // The executable. files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""}) archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) archDirs[archOs], ok = s.BuildZipFile(ctx, module, fpm, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) if !ok { return } }) s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx) s.CreateFuzzPackage(ctx, archDirs, s.FuzzType, pctx) } func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) { Loading @@ -353,27 +495,34 @@ func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) { // ready to handle phony targets created in Soong. In the meantime, this // exports the phony 'fuzz' target and dependencies on packages to // core/main.mk so that we can use dist-for-goals. ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " ")) ctx.Strict("FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS", ctx.Strict(s.fuzzPackagingArchModules, strings.Join(packages, " ")) ctx.Strict(s.fuzzTargetSharedDepsInstallPairs, strings.Join(s.FuzzPackager.SharedLibInstallStrings, " ")) // Preallocate the slice of fuzz targets to minimise memory allocations. s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS") s.PreallocateSlice(ctx, s.allFuzzTargetsName) } // GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for // packaging. func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip { func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, destinationPathPrefix string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip { var files []fuzz.FileToZip fuzzDir := "fuzz" if s.FuzzType == fuzz.AFL { fuzzDir = "afl_fuzz" } for _, library := range sharedLibraries { files = append(files, fuzz.FileToZip{library, "lib"}) files = append(files, fuzz.FileToZip{library, destinationPathPrefix}) // For each architecture-specific shared library dependency, we need to // install it to the output directory. Setup the install destination here, // which will be used by $(copy-many-files) in the Make backend. installDestination := sharedLibraryInstallLocation( library, module.Host(), archString) library, module.Host(), fuzzDir, archString) if (*sharedLibraryInstalled)[installDestination] { continue } Loading @@ -391,7 +540,7 @@ func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, // we want symbolization tools (like `stack`) to be able to find the symbols // in $ANDROID_PRODUCT_OUT/symbols automagically. if !module.Host() { symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString) symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, fuzzDir, archString) symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$") s.SharedLibInstallStrings = append(s.SharedLibInstallStrings, library.String()+":"+symbolsInstallDestination) Loading cc/testing.go +4 −2 Original line number Diff line number Diff line Loading @@ -534,7 +534,8 @@ var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers( android.PrepareForTestWithAndroidBuildComponents, android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest), android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { ctx.RegisterModuleType("cc_fuzz", FuzzFactory) ctx.RegisterModuleType("cc_fuzz", LibFuzzFactory) ctx.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory) ctx.RegisterModuleType("cc_test", TestFactory) ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) Loading Loading @@ -648,7 +649,8 @@ func TestConfig(buildDir string, os android.OsType, env map[string]string, func CreateTestContext(config android.Config) *android.TestContext { ctx := android.NewTestArchContext(config) genrule.RegisterGenruleBuildComponents(ctx) ctx.RegisterModuleType("cc_fuzz", FuzzFactory) ctx.RegisterModuleType("cc_fuzz", LibFuzzFactory) ctx.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory) ctx.RegisterModuleType("cc_test", TestFactory) ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory) Loading fuzz/fuzz_common.go +13 −8 Original line number Diff line number Diff line Loading @@ -27,12 +27,13 @@ import ( "android/soong/android" ) type Lang string type FuzzType string const ( Cc Lang = "" Rust Lang = "rust" Java Lang = "java" Cc FuzzType = "" Rust FuzzType = "rust" Java FuzzType = "java" AFL FuzzType = "AFL" ) var BoolDefault = proptools.BoolDefault Loading @@ -47,6 +48,7 @@ type FuzzPackager struct { Packages android.Paths FuzzTargets map[string]bool SharedLibInstallStrings []string FuzzType FuzzType } type FileToZip struct { Loading Loading @@ -265,7 +267,7 @@ func (f *FuzzConfig) String() string { return string(b) } func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, lang Lang, pctx android.PackageContext) { func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, fuzzType FuzzType, pctx android.PackageContext) { var archOsList []ArchOs for archOs := range archDirs { archOsList = append(archOsList, archOs) Loading @@ -278,12 +280,15 @@ func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs hostOrTarget := archOs.HostOrTarget builder := android.NewRuleBuilder(pctx, ctx) zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip" if lang == Rust { if fuzzType == Rust { zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip" } if lang == Java { if fuzzType == Java { zipFileName = "fuzz-java-" + hostOrTarget + "-" + arch + ".zip" } if fuzzType == AFL { zipFileName = "fuzz-afl-" + hostOrTarget + "-" + arch + ".zip" } outputFile := android.PathForOutput(ctx, zipFileName) s.Packages = append(s.Packages, outputFile) Loading @@ -294,7 +299,6 @@ func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs Flag("-L 0") // No need to try and re-compress the zipfiles. for _, fileToZip := range filesToZip { if fileToZip.DestinationPathPrefix != "" { command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) } else { Loading @@ -313,6 +317,7 @@ func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets str for target, _ := range s.FuzzTargets { fuzzTargets = append(fuzzTargets, target) } sort.Strings(fuzzTargets) ctx.Strict(targets, strings.Join(fuzzTargets, " ")) } Loading Loading
cc/cc.go +11 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,9 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel() ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel() ctx.TopDown("fuzz_deps", fuzzMutatorDeps) ctx.BottomUp("fuzz", fuzzMutator) ctx.BottomUp("coverage", coverageMutator).Parallel() ctx.TopDown("afdo_deps", afdoDepsMutator) Loading Loading @@ -838,6 +841,7 @@ type Module struct { stl *stl sanitize *sanitize coverage *coverage fuzzer *fuzzer sabi *sabi vndkdep *vndkdep lto *lto Loading Loading @@ -1163,6 +1167,9 @@ func (c *Module) Init() android.Module { if c.coverage != nil { c.AddProperties(c.coverage.props()...) } if c.fuzzer != nil { c.AddProperties(c.fuzzer.props()...) } if c.sabi != nil { c.AddProperties(c.sabi.props()...) } Loading Loading @@ -1680,6 +1687,7 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo module.stl = &stl{} module.sanitize = &sanitize{} module.coverage = &coverage{} module.fuzzer = &fuzzer{} module.sabi = &sabi{} module.vndkdep = &vndkdep{} module.lto = <o{} Loading Loading @@ -1901,6 +1909,9 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if c.coverage != nil { flags, deps = c.coverage.flags(ctx, flags, deps) } if c.fuzzer != nil { flags = c.fuzzer.flags(ctx, flags) } if c.lto != nil { flags = c.lto.flags(ctx, flags) } Loading
cc/cc_test.go +119 −0 Original line number Diff line number Diff line Loading @@ -3342,6 +3342,125 @@ func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) { `) } func TestAFLFuzzTarget(t *testing.T) { ctx := testCc(t, ` cc_afl_fuzz { name: "test_afl_fuzz_target", srcs: ["foo.c"], host_supported: true, static_libs: [ "afl_fuzz_static_lib", ], shared_libs: [ "afl_fuzz_shared_lib", ], } cc_fuzz { name: "test_fuzz_target", srcs: ["foo.c"], static_libs: [ "afl_fuzz_static_lib", "libfuzzer_only_static_lib", ], shared_libs: [ "afl_fuzz_shared_lib", ], } cc_library { name: "afl_fuzz_static_lib", host_supported: true, srcs: ["static_file.c"], } cc_library { name: "libfuzzer_only_static_lib", host_supported: true, srcs: ["static_file.c"], } cc_library { name: "afl_fuzz_shared_lib", host_supported: true, srcs: ["shared_file.c"], static_libs: [ "second_static_lib", ], } cc_library_headers { name: "libafl_headers", vendor_available: true, host_supported: true, export_include_dirs: [ "include", "instrumentation", ], } cc_object { name: "afl-compiler-rt", vendor_available: true, host_supported: true, cflags: [ "-fPIC", ], srcs: [ "instrumentation/afl-compiler-rt.o.c", ], } cc_library { name: "second_static_lib", host_supported: true, srcs: ["second_file.c"], } filegroup { name: "aflpp_driver", srcs: [ "aflpp_driver.c", ], }`) checkPcGuardFlag := func( modName string, variantName string, shouldHave bool) { cc := ctx.ModuleForTests(modName, variantName).Rule("cc") cFlags, ok := cc.Args["cFlags"] if !ok { t.Errorf("Could not find cFlags for module %s and variant %s", modName, variantName) } if strings.Contains( cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave { t.Errorf("Flag was found: %t. Expected to find flag: %t. "+ "Test failed for module %s and variant %s", !shouldHave, shouldHave, modName, variantName) } } for _, vnt := range ctx.ModuleVariantsForTests("libfuzzer_only_static_lib") { if strings.Contains(vnt, "fuzzer_afl") { t.Errorf("libfuzzer_only_static_lib has afl variant and should not") } } moduleName := "test_afl_fuzz_target" variantName := "android_arm64_armv8-a_fuzzer_afl" checkPcGuardFlag(moduleName, variantName, true) moduleName = "afl_fuzz_static_lib" variantName = "android_arm64_armv8-a_static" checkPcGuardFlag(moduleName, variantName, false) checkPcGuardFlag(moduleName, variantName+"_fuzzer", false) checkPcGuardFlag(moduleName, variantName+"_fuzzer_afl", true) moduleName = "second_static_lib" checkPcGuardFlag(moduleName, variantName, false) checkPcGuardFlag(moduleName, variantName+"_fuzzer", false) checkPcGuardFlag(moduleName, variantName+"_fuzzer_afl", true) ctx.ModuleForTests("afl_fuzz_shared_lib", "android_arm64_armv8-a_shared").Rule("cc") ctx.ModuleForTests("afl_fuzz_shared_lib", "android_arm64_armv8-a_shared_fuzzer_afl").Rule("cc") } // Simple smoke test for the cc_fuzz target that ensures the rule compiles // correctly. func TestFuzzTarget(t *testing.T) { Loading
cc/fuzz.go +210 −61 Original line number Diff line number Diff line Loading @@ -27,29 +27,113 @@ import ( ) func init() { android.RegisterModuleType("cc_fuzz", FuzzFactory) android.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory) android.RegisterModuleType("cc_fuzz", LibFuzzFactory) android.RegisterSingletonType("cc_fuzz_packaging", fuzzPackagingFactory) android.RegisterSingletonType("cc_afl_fuzz_packaging", fuzzAFLPackagingFactory) } type FuzzProperties struct { AFLEnabled bool `blueprint:"mutated"` AFLAddFlags bool `blueprint:"mutated"` } type fuzzer struct { Properties FuzzProperties } func (fuzzer *fuzzer) flags(ctx ModuleContext, flags Flags) Flags { if fuzzer.Properties.AFLAddFlags { flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-coverage=trace-pc-guard") } return flags } func (fuzzer *fuzzer) props() []interface{} { return []interface{}{&fuzzer.Properties} } func fuzzMutatorDeps(mctx android.TopDownMutatorContext) { currentModule, ok := mctx.Module().(*Module) if !ok { return } if currentModule.fuzzer == nil || !currentModule.fuzzer.Properties.AFLEnabled { return } mctx.WalkDeps(func(child android.Module, parent android.Module) bool { c, ok := child.(*Module) if !ok { return false } if c.sanitize == nil { return false } isFuzzerPointer := c.sanitize.getSanitizerBoolPtr(Fuzzer) if isFuzzerPointer == nil || !*isFuzzerPointer { return false } if c.fuzzer == nil { return false } c.fuzzer.Properties.AFLEnabled = true c.fuzzer.Properties.AFLAddFlags = true return true }) } func fuzzMutator(mctx android.BottomUpMutatorContext) { if c, ok := mctx.Module().(*Module); ok && c.fuzzer != nil { if !c.fuzzer.Properties.AFLEnabled { return } if c.Binary() { m := mctx.CreateVariations("afl") m[0].(*Module).fuzzer.Properties.AFLEnabled = true m[0].(*Module).fuzzer.Properties.AFLAddFlags = true } else { m := mctx.CreateVariations("", "afl") m[0].(*Module).fuzzer.Properties.AFLEnabled = false m[0].(*Module).fuzzer.Properties.AFLAddFlags = false m[1].(*Module).fuzzer.Properties.AFLEnabled = true m[1].(*Module).fuzzer.Properties.AFLAddFlags = true } } } // cc_fuzz creates a host/device fuzzer binary. Host binaries can be found at // $ANDROID_HOST_OUT/fuzz/, and device binaries can be found at /data/fuzz on // your device, or $ANDROID_PRODUCT_OUT/data/fuzz in your build tree. func FuzzFactory() android.Module { module := NewFuzz(android.HostAndDeviceSupported) func LibFuzzFactory() android.Module { module := NewFuzzer(android.HostAndDeviceSupported, fuzz.Cc) return module.Init() } func NewFuzzInstaller() *baseInstaller { return NewBaseInstaller("fuzz", "fuzz", InstallInData) // cc_afl_fuzz creates a host/device AFL++ fuzzer binary. // AFL++ is an open source framework used to fuzz libraries // Host binaries can be found at $ANDROID_HOST_OUT/afl_fuzz/ and device // binaries can be found at $ANDROID_PRODUCT_OUT/data/afl_fuzz in your // build tree func AFLFuzzFactory() android.Module { module := NewFuzzer(android.HostAndDeviceSupported, fuzz.AFL) return module.Init() } type fuzzBinary struct { *binaryDecorator *baseCompiler fuzzPackagedModule fuzz.FuzzPackagedModule installedSharedDeps []string fuzzType fuzz.FuzzType } func (fuzz *fuzzBinary) fuzzBinary() bool { Loading @@ -66,12 +150,18 @@ func (fuzz *fuzzBinary) linkerInit(ctx BaseModuleContext) { fuzz.binaryDecorator.linkerInit(ctx) } func (fuzz *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary(ctx.toolchain())) deps = fuzz.binaryDecorator.linkerDeps(ctx, deps) func (fuzzBin *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { if fuzzBin.fuzzType == fuzz.AFL { deps.HeaderLibs = append(deps.HeaderLibs, "libafl_headers") deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps) return deps } else { deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary(ctx.toolchain())) deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps) return deps } } func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags = fuzz.binaryDecorator.linkerFlags(ctx, flags) Loading @@ -80,6 +170,7 @@ func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { // target packages. flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`) flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/lib`) return flags } Loading Loading @@ -149,63 +240,68 @@ func IsValidSharedDependency(dependency android.Module) bool { } func sharedLibraryInstallLocation( libraryPath android.Path, isHost bool, archString string) string { libraryPath android.Path, isHost bool, fuzzDir string, archString string) string { installLocation := "$(PRODUCT_OUT)/data" if isHost { installLocation = "$(HOST_OUT)" } installLocation = filepath.Join( installLocation, "fuzz", archString, "lib", libraryPath.Base()) installLocation, fuzzDir, archString, "lib", libraryPath.Base()) return installLocation } // Get the device-only shared library symbols install directory. func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, archString string) string { return filepath.Join("$(PRODUCT_OUT)/symbols/data/fuzz/", archString, "/lib/", libraryPath.Base()) func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, fuzzDir string, archString string) string { return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, "/lib/", libraryPath.Base()) } func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { fuzz.binaryDecorator.baseInstaller.dir = filepath.Join( "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join( "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseInstaller.install(ctx, file) func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) { installBase := "fuzz" if fuzzBin.fuzzType == fuzz.AFL { installBase = "afl_fuzz" } fuzzBin.binaryDecorator.baseInstaller.dir = filepath.Join( installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzzBin.binaryDecorator.baseInstaller.dir64 = filepath.Join( installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzzBin.binaryDecorator.baseInstaller.install(ctx, file) fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus) fuzzBin.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Corpus) builder := android.NewRuleBuilder(pctx, ctx) intermediateDir := android.PathForModuleOut(ctx, "corpus") for _, entry := range fuzz.fuzzPackagedModule.Corpus { for _, entry := range fuzzBin.fuzzPackagedModule.Corpus { builder.Command().Text("cp"). Input(entry). Output(intermediateDir.Join(ctx, entry.Base())) } builder.Build("copy_corpus", "copy corpus") fuzz.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir fuzzBin.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data) fuzzBin.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Data) builder = android.NewRuleBuilder(pctx, ctx) intermediateDir = android.PathForModuleOut(ctx, "data") for _, entry := range fuzz.fuzzPackagedModule.Data { for _, entry := range fuzzBin.fuzzPackagedModule.Data { builder.Command().Text("cp"). Input(entry). Output(intermediateDir.Join(ctx, entry.Rel())) } builder.Build("copy_data", "copy data") fuzz.fuzzPackagedModule.DataIntermediateDir = intermediateDir fuzzBin.fuzzPackagedModule.DataIntermediateDir = intermediateDir if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil { fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary) if fuzz.fuzzPackagedModule.Dictionary.Ext() != ".dict" { if fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary != nil { fuzzBin.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary) if fuzzBin.fuzzPackagedModule.Dictionary.Ext() != ".dict" { ctx.PropertyErrorf("dictionary", "Fuzzer dictionary %q does not have '.dict' extension", fuzz.fuzzPackagedModule.Dictionary.String()) fuzzBin.fuzzPackagedModule.Dictionary.String()) } } if fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil { if fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil { configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json") android.WriteFileRule(ctx, configPath, fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config.String()) fuzz.fuzzPackagedModule.Config = configPath android.WriteFileRule(ctx, configPath, fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config.String()) fuzzBin.fuzzPackagedModule.Config = configPath } // Grab the list of required shared libraries. Loading @@ -225,31 +321,36 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { }) for _, lib := range sharedLibraries { fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps, sharedLibraryInstallLocation( lib, ctx.Host(), ctx.Arch().ArchType.String())) lib, ctx.Host(), installBase, ctx.Arch().ArchType.String())) // Also add the dependency on the shared library symbols dir. if !ctx.Host() { fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, sharedLibrarySymbolsInstallLocation(lib, ctx.Arch().ArchType.String())) fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps, sharedLibrarySymbolsInstallLocation(lib, installBase, ctx.Arch().ArchType.String())) } } } func NewFuzz(hod android.HostOrDeviceSupported) *Module { func NewFuzzer(hod android.HostOrDeviceSupported, fuzzType fuzz.FuzzType) *Module { module, binary := newBinary(hod, false) baseInstallerPath := "fuzz" if fuzzType == fuzz.AFL { baseInstallerPath = "afl_fuzz" } binary.baseInstaller = NewFuzzInstaller() binary.baseInstaller = NewBaseInstaller(baseInstallerPath, baseInstallerPath, InstallInData) module.sanitize.SetSanitizer(Fuzzer, true) fuzz := &fuzzBinary{ fuzzBin := &fuzzBinary{ binaryDecorator: binary, baseCompiler: NewBaseCompiler(), fuzzType: fuzzType, } module.compiler = fuzz module.linker = fuzz module.installer = fuzz module.compiler = fuzzBin module.linker = fuzzBin module.installer = fuzzBin // The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin. android.AddLoadHook(module, func(ctx android.LoadHookContext) { Loading @@ -268,6 +369,17 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module { ctx.AppendProperties(&disableDarwinAndLinuxBionic) }) if fuzzType == fuzz.AFL { // Add cc_objects to Srcs fuzzBin.baseCompiler.Properties.Srcs = append(fuzzBin.baseCompiler.Properties.Srcs, ":aflpp_driver", ":afl-compiler-rt") module.fuzzer.Properties.AFLEnabled = true module.compiler.appendCflags([]string{ "-Wno-unused-result", "-Wno-unused-parameter", "-Wno-unused-function", }) } return module } Loading @@ -275,10 +387,30 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module { // their architecture & target/host specific zip file. type ccFuzzPackager struct { fuzz.FuzzPackager fuzzPackagingArchModules string fuzzTargetSharedDepsInstallPairs string allFuzzTargetsName string } func fuzzPackagingFactory() android.Singleton { return &ccFuzzPackager{} fuzzPackager := &ccFuzzPackager{ fuzzPackagingArchModules: "SOONG_FUZZ_PACKAGING_ARCH_MODULES", fuzzTargetSharedDepsInstallPairs: "FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS", allFuzzTargetsName: "ALL_FUZZ_TARGETS", } fuzzPackager.FuzzType = fuzz.Cc return fuzzPackager } func fuzzAFLPackagingFactory() android.Singleton { fuzzPackager := &ccFuzzPackager{ fuzzPackagingArchModules: "SOONG_AFL_FUZZ_PACKAGING_ARCH_MODULES", fuzzTargetSharedDepsInstallPairs: "AFL_FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS", allFuzzTargetsName: "ALL_AFL_FUZZ_TARGETS", } fuzzPackager.FuzzType = fuzz.AFL return fuzzPackager } func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { Loading Loading @@ -306,8 +438,9 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { return } sharedLibsInstallDirPrefix := "lib" fuzzModule, ok := ccModule.compiler.(*fuzzBinary) if !ok { if !ok || fuzzModule.fuzzType != s.FuzzType { return } Loading @@ -316,8 +449,18 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { hostOrTargetString = "host" } fpm := fuzz.FuzzPackagedModule{} if ok { fpm = fuzzModule.fuzzPackagedModule } intermediatePath := "fuzz" if s.FuzzType == fuzz.AFL { intermediatePath = "afl_fuzz" } archString := ccModule.Arch().ArchType.String() archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString) archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString) archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()} // Grab the list of required shared libraries. Loading @@ -327,22 +470,21 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { builder := android.NewRuleBuilder(pctx, ctx) // Package the corpus, data, dict and config into a zipfile. files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder) files = s.PackageArtifacts(ctx, module, fpm, archDir, builder) // Package shared libraries files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...) files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...) // The executable. files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""}) archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) archDirs[archOs], ok = s.BuildZipFile(ctx, module, fpm, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) if !ok { return } }) s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx) s.CreateFuzzPackage(ctx, archDirs, s.FuzzType, pctx) } func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) { Loading @@ -353,27 +495,34 @@ func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) { // ready to handle phony targets created in Soong. In the meantime, this // exports the phony 'fuzz' target and dependencies on packages to // core/main.mk so that we can use dist-for-goals. ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " ")) ctx.Strict("FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS", ctx.Strict(s.fuzzPackagingArchModules, strings.Join(packages, " ")) ctx.Strict(s.fuzzTargetSharedDepsInstallPairs, strings.Join(s.FuzzPackager.SharedLibInstallStrings, " ")) // Preallocate the slice of fuzz targets to minimise memory allocations. s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS") s.PreallocateSlice(ctx, s.allFuzzTargetsName) } // GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for // packaging. func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip { func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, destinationPathPrefix string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip { var files []fuzz.FileToZip fuzzDir := "fuzz" if s.FuzzType == fuzz.AFL { fuzzDir = "afl_fuzz" } for _, library := range sharedLibraries { files = append(files, fuzz.FileToZip{library, "lib"}) files = append(files, fuzz.FileToZip{library, destinationPathPrefix}) // For each architecture-specific shared library dependency, we need to // install it to the output directory. Setup the install destination here, // which will be used by $(copy-many-files) in the Make backend. installDestination := sharedLibraryInstallLocation( library, module.Host(), archString) library, module.Host(), fuzzDir, archString) if (*sharedLibraryInstalled)[installDestination] { continue } Loading @@ -391,7 +540,7 @@ func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, // we want symbolization tools (like `stack`) to be able to find the symbols // in $ANDROID_PRODUCT_OUT/symbols automagically. if !module.Host() { symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString) symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, fuzzDir, archString) symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$") s.SharedLibInstallStrings = append(s.SharedLibInstallStrings, library.String()+":"+symbolsInstallDestination) Loading
cc/testing.go +4 −2 Original line number Diff line number Diff line Loading @@ -534,7 +534,8 @@ var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers( android.PrepareForTestWithAndroidBuildComponents, android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest), android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { ctx.RegisterModuleType("cc_fuzz", FuzzFactory) ctx.RegisterModuleType("cc_fuzz", LibFuzzFactory) ctx.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory) ctx.RegisterModuleType("cc_test", TestFactory) ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) Loading Loading @@ -648,7 +649,8 @@ func TestConfig(buildDir string, os android.OsType, env map[string]string, func CreateTestContext(config android.Config) *android.TestContext { ctx := android.NewTestArchContext(config) genrule.RegisterGenruleBuildComponents(ctx) ctx.RegisterModuleType("cc_fuzz", FuzzFactory) ctx.RegisterModuleType("cc_fuzz", LibFuzzFactory) ctx.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory) ctx.RegisterModuleType("cc_test", TestFactory) ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory) Loading
fuzz/fuzz_common.go +13 −8 Original line number Diff line number Diff line Loading @@ -27,12 +27,13 @@ import ( "android/soong/android" ) type Lang string type FuzzType string const ( Cc Lang = "" Rust Lang = "rust" Java Lang = "java" Cc FuzzType = "" Rust FuzzType = "rust" Java FuzzType = "java" AFL FuzzType = "AFL" ) var BoolDefault = proptools.BoolDefault Loading @@ -47,6 +48,7 @@ type FuzzPackager struct { Packages android.Paths FuzzTargets map[string]bool SharedLibInstallStrings []string FuzzType FuzzType } type FileToZip struct { Loading Loading @@ -265,7 +267,7 @@ func (f *FuzzConfig) String() string { return string(b) } func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, lang Lang, pctx android.PackageContext) { func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, fuzzType FuzzType, pctx android.PackageContext) { var archOsList []ArchOs for archOs := range archDirs { archOsList = append(archOsList, archOs) Loading @@ -278,12 +280,15 @@ func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs hostOrTarget := archOs.HostOrTarget builder := android.NewRuleBuilder(pctx, ctx) zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip" if lang == Rust { if fuzzType == Rust { zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip" } if lang == Java { if fuzzType == Java { zipFileName = "fuzz-java-" + hostOrTarget + "-" + arch + ".zip" } if fuzzType == AFL { zipFileName = "fuzz-afl-" + hostOrTarget + "-" + arch + ".zip" } outputFile := android.PathForOutput(ctx, zipFileName) s.Packages = append(s.Packages, outputFile) Loading @@ -294,7 +299,6 @@ func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs Flag("-L 0") // No need to try and re-compress the zipfiles. for _, fileToZip := range filesToZip { if fileToZip.DestinationPathPrefix != "" { command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) } else { Loading @@ -313,6 +317,7 @@ func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets str for target, _ := range s.FuzzTargets { fuzzTargets = append(fuzzTargets, target) } sort.Strings(fuzzTargets) ctx.Strict(targets, strings.Join(fuzzTargets, " ")) } Loading