Merge "Updated the way we build AFL++ fuzz binaries"
diff --git a/cc/cc.go b/cc/cc.go
index bc95813..fd57e9e 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -62,7 +62,6 @@
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
ctx.TopDown("fuzz_deps", fuzzMutatorDeps)
- ctx.BottomUp("fuzz", fuzzMutator)
ctx.BottomUp("coverage", coverageMutator).Parallel()
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 24732bf..ac1a49f 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3343,8 +3343,8 @@
}
func TestAFLFuzzTarget(t *testing.T) {
- ctx := testCc(t, `
- cc_afl_fuzz {
+ bp := `
+ cc_fuzz {
name: "test_afl_fuzz_target",
srcs: ["foo.c"],
host_supported: true,
@@ -3354,17 +3354,10 @@
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",
- ],
+ fuzzing_frameworks: {
+ afl: true,
+ libfuzzer: false,
+ },
}
cc_library {
name: "afl_fuzz_static_lib",
@@ -3409,12 +3402,19 @@
host_supported: true,
srcs: ["second_file.c"],
}
- filegroup {
+ cc_object {
name: "aflpp_driver",
+ host_supported: true,
srcs: [
"aflpp_driver.c",
],
- }`)
+ }`
+
+ testEnv := map[string]string{
+ "FUZZ_FRAMEWORK": "AFL",
+ }
+
+ ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
checkPcGuardFlag := func(
modName string, variantName string, shouldHave bool) {
@@ -3434,31 +3434,28 @@
}
}
- 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)
+ hostVariant := "linux_glibc_x86_64"
+ armVariant := "android_arm64_armv8-a"
+ checkPcGuardFlag(moduleName, armVariant+"_fuzzer", true)
+ checkPcGuardFlag(moduleName, hostVariant+"_fuzzer", 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)
+ checkPcGuardFlag(moduleName, armVariant+"_static", false)
+ checkPcGuardFlag(moduleName, armVariant+"_static_fuzzer", true)
+ checkPcGuardFlag(moduleName, hostVariant+"_static", false)
+ checkPcGuardFlag(moduleName, hostVariant+"_static_fuzzer", true)
moduleName = "second_static_lib"
- checkPcGuardFlag(moduleName, variantName, false)
- checkPcGuardFlag(moduleName, variantName+"_fuzzer", false)
- checkPcGuardFlag(moduleName, variantName+"_fuzzer_afl", true)
+ checkPcGuardFlag(moduleName, armVariant+"_static", false)
+ checkPcGuardFlag(moduleName, armVariant+"_static_fuzzer", true)
+ checkPcGuardFlag(moduleName, hostVariant+"_static", false)
+ checkPcGuardFlag(moduleName, hostVariant+"_static_fuzzer", 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")
+ "android_arm64_armv8-a_shared_fuzzer").Rule("cc")
}
// Simple smoke test for the cc_fuzz target that ensures the rule compiles
diff --git a/cc/fuzz.go b/cc/fuzz.go
index d6af97f..dfc718e 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -27,15 +27,12 @@
)
func init() {
- 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"`
+ FuzzFramework fuzz.Framework `blueprint:"mutated"`
}
type fuzzer struct {
@@ -43,8 +40,13 @@
}
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")
+ if fuzzer.Properties.FuzzFramework == fuzz.AFL {
+ flags.Local.CFlags = append(flags.Local.CFlags, []string{
+ "-fsanitize-coverage=trace-pc-guard",
+ "-Wno-unused-result",
+ "-Wno-unused-parameter",
+ "-Wno-unused-function",
+ }...)
}
return flags
@@ -60,7 +62,7 @@
return
}
- if currentModule.fuzzer == nil || !currentModule.fuzzer.Properties.AFLEnabled {
+ if currentModule.fuzzer == nil {
return
}
@@ -83,48 +85,16 @@
return false
}
- c.fuzzer.Properties.AFLEnabled = true
- c.fuzzer.Properties.AFLAddFlags = true
+ c.fuzzer.Properties.FuzzFramework = currentModule.fuzzer.Properties.FuzzFramework
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 LibFuzzFactory() android.Module {
- module := NewFuzzer(android.HostAndDeviceSupported, fuzz.Cc)
- return module.Init()
-}
-
-// 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)
+ module := NewFuzzer(android.HostAndDeviceSupported)
return module.Init()
}
@@ -133,7 +103,6 @@
*baseCompiler
fuzzPackagedModule fuzz.FuzzPackagedModule
installedSharedDeps []string
- fuzzType fuzz.FuzzType
}
func (fuzz *fuzzBinary) fuzzBinary() bool {
@@ -143,6 +112,7 @@
func (fuzz *fuzzBinary) linkerProps() []interface{} {
props := fuzz.binaryDecorator.linkerProps()
props = append(props, &fuzz.fuzzPackagedModule.FuzzProperties)
+
return props
}
@@ -151,16 +121,14 @@
}
func (fuzzBin *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
- if fuzzBin.fuzzType == fuzz.AFL {
+ if ctx.Config().Getenv("FUZZ_FRAMEWORK") == "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
}
+
+ deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps)
+ return deps
}
func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
@@ -257,9 +225,6 @@
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())
@@ -333,12 +298,9 @@
}
}
-func NewFuzzer(hod android.HostOrDeviceSupported, fuzzType fuzz.FuzzType) *Module {
+func NewFuzzer(hod android.HostOrDeviceSupported) *Module {
module, binary := newBinary(hod, false)
baseInstallerPath := "fuzz"
- if fuzzType == fuzz.AFL {
- baseInstallerPath = "afl_fuzz"
- }
binary.baseInstaller = NewBaseInstaller(baseInstallerPath, baseInstallerPath, InstallInData)
module.sanitize.SetSanitizer(Fuzzer, true)
@@ -346,12 +308,13 @@
fuzzBin := &fuzzBinary{
binaryDecorator: binary,
baseCompiler: NewBaseCompiler(),
- fuzzType: fuzzType,
}
module.compiler = fuzzBin
module.linker = fuzzBin
module.installer = fuzzBin
+ module.fuzzer.Properties.FuzzFramework = fuzz.LibFuzzer
+
// The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin.
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
disableDarwinAndLinuxBionic := struct {
@@ -367,18 +330,18 @@
disableDarwinAndLinuxBionic.Target.Darwin.Enabled = BoolPtr(false)
disableDarwinAndLinuxBionic.Target.Linux_bionic.Enabled = BoolPtr(false)
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",
- })
- }
+ targetFramework := fuzz.GetFramework(ctx, fuzz.Cc)
+ if !fuzz.IsValidFrameworkForModule(targetFramework, fuzz.Cc, fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzzing_frameworks) {
+ ctx.Module().Disable()
+ return
+ }
+
+ if targetFramework == fuzz.AFL {
+ fuzzBin.baseCompiler.Properties.Srcs = append(fuzzBin.baseCompiler.Properties.Srcs, ":aflpp_driver", ":afl-compiler-rt")
+ module.fuzzer.Properties.FuzzFramework = fuzz.AFL
+ }
+ })
return module
}
@@ -399,17 +362,6 @@
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
}
@@ -440,7 +392,7 @@
sharedLibsInstallDirPrefix := "lib"
fuzzModule, ok := ccModule.compiler.(*fuzzBinary)
- if !ok || fuzzModule.fuzzType != s.FuzzType {
+ if !ok {
return
}
@@ -455,9 +407,6 @@
}
intermediatePath := "fuzz"
- if s.FuzzType == fuzz.AFL {
- intermediatePath = "afl_fuzz"
- }
archString := ccModule.Arch().ArchType.String()
archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString)
@@ -484,7 +433,7 @@
}
})
- s.CreateFuzzPackage(ctx, archDirs, s.FuzzType, pctx)
+ s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx)
}
func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
@@ -511,9 +460,6 @@
var files []fuzz.FileToZip
fuzzDir := "fuzz"
- if s.FuzzType == fuzz.AFL {
- fuzzDir = "afl_fuzz"
- }
for _, library := range sharedLibraries {
files = append(files, fuzz.FileToZip{library, destinationPathPrefix})
diff --git a/cc/testing.go b/cc/testing.go
index d70ec9b..79ae3c3 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -531,7 +531,6 @@
android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
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)
@@ -646,7 +645,6 @@
ctx := android.NewTestArchContext(config)
genrule.RegisterGenruleBuildComponents(ctx)
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)
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index 2474cbc..c8cd21b 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -27,13 +27,21 @@
"android/soong/android"
)
-type FuzzType string
+type Lang string
const (
- Cc FuzzType = ""
- Rust FuzzType = "rust"
- Java FuzzType = "java"
- AFL FuzzType = "AFL"
+ Cc Lang = "cc"
+ Rust Lang = "rust"
+ Java Lang = "java"
+)
+
+type Framework string
+
+const (
+ AFL Framework = "afl"
+ LibFuzzer Framework = "libfuzzer"
+ Jazzer Framework = "jazzer"
+ UnknownFramework Framework = "unknownframework"
)
var BoolDefault = proptools.BoolDefault
@@ -48,7 +56,6 @@
Packages android.Paths
FuzzTargets map[string]bool
SharedLibInstallStrings []string
- FuzzType FuzzType
}
type FileToZip struct {
@@ -146,6 +153,12 @@
IsJni *bool `json:"is_jni,omitempty"`
}
+type FuzzFrameworks struct {
+ Afl *bool
+ Libfuzzer *bool
+ Jazzer *bool
+}
+
type FuzzProperties struct {
// Optional list of seed files to be installed to the fuzz target's output
// directory.
@@ -155,6 +168,10 @@
Data []string `android:"path"`
// Optional dictionary to be installed to the fuzz target's output directory.
Dictionary *string `android:"path"`
+ // Define the fuzzing frameworks this fuzz target can be built for. If
+ // empty then the fuzz target will be available to be built for all fuzz
+ // frameworks available
+ Fuzzing_frameworks *FuzzFrameworks
// Config for running the target on fuzzing infrastructure.
Fuzz_config *FuzzConfig
}
@@ -169,6 +186,49 @@
DataIntermediateDir android.Path
}
+func GetFramework(ctx android.LoadHookContext, lang Lang) Framework {
+ framework := ctx.Config().Getenv("FUZZ_FRAMEWORK")
+
+ if lang == Cc {
+ switch strings.ToLower(framework) {
+ case "":
+ return LibFuzzer
+ case "libfuzzer":
+ return LibFuzzer
+ case "afl":
+ return AFL
+ }
+ } else if lang == Rust {
+ return LibFuzzer
+ } else if lang == Java {
+ return Jazzer
+ }
+
+ ctx.ModuleErrorf(fmt.Sprintf("%s is not a valid fuzzing framework for %s", framework, lang))
+ return UnknownFramework
+}
+
+func IsValidFrameworkForModule(targetFramework Framework, lang Lang, moduleFrameworks *FuzzFrameworks) bool {
+ if targetFramework == UnknownFramework {
+ return false
+ }
+
+ if moduleFrameworks == nil {
+ return true
+ }
+
+ switch targetFramework {
+ case LibFuzzer:
+ return proptools.BoolDefault(moduleFrameworks.Libfuzzer, true)
+ case AFL:
+ return proptools.BoolDefault(moduleFrameworks.Afl, true)
+ case Jazzer:
+ return proptools.BoolDefault(moduleFrameworks.Jazzer, true)
+ default:
+ panic("%s is not supported as a fuzz framework")
+ }
+}
+
func IsValid(fuzzModule FuzzModule) bool {
// Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
// fuzz targets we're going to package anyway.
@@ -267,7 +327,7 @@
return string(b)
}
-func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, fuzzType FuzzType, pctx android.PackageContext) {
+func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, fuzzType Lang, pctx android.PackageContext) {
var archOsList []ArchOs
for archOs := range archDirs {
archOsList = append(archOsList, archOs)
@@ -286,9 +346,7 @@
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)