Adding support for building AFLpp

Test: Build AFL fuzzers locally and ran them

Change-Id: Ie4fbd258c87663cf81d7d64d575b3da1d5febc17
This commit is contained in:
Cory Barker
2022-06-07 20:12:06 +00:00
parent 87d74dc54e
commit a1da26fa9b
6 changed files with 358 additions and 72 deletions

View File

@@ -61,6 +61,9 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) {
ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel() ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel() ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
ctx.TopDown("fuzz_deps", fuzzMutatorDeps)
ctx.BottomUp("fuzz", fuzzMutator)
ctx.BottomUp("coverage", coverageMutator).Parallel() ctx.BottomUp("coverage", coverageMutator).Parallel()
ctx.TopDown("afdo_deps", afdoDepsMutator) ctx.TopDown("afdo_deps", afdoDepsMutator)
@@ -838,6 +841,7 @@ type Module struct {
stl *stl stl *stl
sanitize *sanitize sanitize *sanitize
coverage *coverage coverage *coverage
fuzzer *fuzzer
sabi *sabi sabi *sabi
vndkdep *vndkdep vndkdep *vndkdep
lto *lto lto *lto
@@ -1163,6 +1167,9 @@ func (c *Module) Init() android.Module {
if c.coverage != nil { if c.coverage != nil {
c.AddProperties(c.coverage.props()...) c.AddProperties(c.coverage.props()...)
} }
if c.fuzzer != nil {
c.AddProperties(c.fuzzer.props()...)
}
if c.sabi != nil { if c.sabi != nil {
c.AddProperties(c.sabi.props()...) c.AddProperties(c.sabi.props()...)
} }
@@ -1680,6 +1687,7 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo
module.stl = &stl{} module.stl = &stl{}
module.sanitize = &sanitize{} module.sanitize = &sanitize{}
module.coverage = &coverage{} module.coverage = &coverage{}
module.fuzzer = &fuzzer{}
module.sabi = &sabi{} module.sabi = &sabi{}
module.vndkdep = &vndkdep{} module.vndkdep = &vndkdep{}
module.lto = &lto{} module.lto = &lto{}
@@ -1901,6 +1909,9 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
if c.coverage != nil { if c.coverage != nil {
flags, deps = c.coverage.flags(ctx, flags, deps) flags, deps = c.coverage.flags(ctx, flags, deps)
} }
if c.fuzzer != nil {
flags = c.fuzzer.flags(ctx, flags)
}
if c.lto != nil { if c.lto != nil {
flags = c.lto.flags(ctx, flags) flags = c.lto.flags(ctx, flags)
} }

View File

@@ -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 // Simple smoke test for the cc_fuzz target that ensures the rule compiles
// correctly. // correctly.
func TestFuzzTarget(t *testing.T) { func TestFuzzTarget(t *testing.T) {

View File

@@ -27,29 +27,113 @@ import (
) )
func init() { 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_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 // 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 // $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. // your device, or $ANDROID_PRODUCT_OUT/data/fuzz in your build tree.
func FuzzFactory() android.Module { func LibFuzzFactory() android.Module {
module := NewFuzz(android.HostAndDeviceSupported) module := NewFuzzer(android.HostAndDeviceSupported, fuzz.Cc)
return module.Init() return module.Init()
} }
func NewFuzzInstaller() *baseInstaller { // cc_afl_fuzz creates a host/device AFL++ fuzzer binary.
return NewBaseInstaller("fuzz", "fuzz", InstallInData) // 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 { type fuzzBinary struct {
*binaryDecorator *binaryDecorator
*baseCompiler *baseCompiler
fuzzPackagedModule fuzz.FuzzPackagedModule
fuzzPackagedModule fuzz.FuzzPackagedModule
installedSharedDeps []string installedSharedDeps []string
fuzzType fuzz.FuzzType
} }
func (fuzz *fuzzBinary) fuzzBinary() bool { func (fuzz *fuzzBinary) fuzzBinary() bool {
@@ -66,11 +150,17 @@ func (fuzz *fuzzBinary) linkerInit(ctx BaseModuleContext) {
fuzz.binaryDecorator.linkerInit(ctx) fuzz.binaryDecorator.linkerInit(ctx)
} }
func (fuzz *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps { func (fuzzBin *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
deps.StaticLibs = append(deps.StaticLibs, if fuzzBin.fuzzType == fuzz.AFL {
config.LibFuzzerRuntimeLibrary(ctx.toolchain())) deps.HeaderLibs = append(deps.HeaderLibs, "libafl_headers")
deps = fuzz.binaryDecorator.linkerDeps(ctx, deps) deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps)
return 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 { func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
@@ -80,6 +170,7 @@ func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
// target packages. // target packages.
flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`) flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`)
flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/lib`) flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/lib`)
return flags return flags
} }
@@ -149,63 +240,68 @@ func IsValidSharedDependency(dependency android.Module) bool {
} }
func sharedLibraryInstallLocation( func sharedLibraryInstallLocation(
libraryPath android.Path, isHost bool, archString string) string { libraryPath android.Path, isHost bool, fuzzDir string, archString string) string {
installLocation := "$(PRODUCT_OUT)/data" installLocation := "$(PRODUCT_OUT)/data"
if isHost { if isHost {
installLocation = "$(HOST_OUT)" installLocation = "$(HOST_OUT)"
} }
installLocation = filepath.Join( installLocation = filepath.Join(
installLocation, "fuzz", archString, "lib", libraryPath.Base()) installLocation, fuzzDir, archString, "lib", libraryPath.Base())
return installLocation return installLocation
} }
// Get the device-only shared library symbols install directory. // Get the device-only shared library symbols install directory.
func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, archString string) string { func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, fuzzDir string, archString string) string {
return filepath.Join("$(PRODUCT_OUT)/symbols/data/fuzz/", archString, "/lib/", libraryPath.Base()) return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, "/lib/", libraryPath.Base())
} }
func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
fuzz.binaryDecorator.baseInstaller.dir = filepath.Join( installBase := "fuzz"
"fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) if fuzzBin.fuzzType == fuzz.AFL {
fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join( installBase = "afl_fuzz"
"fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) }
fuzz.binaryDecorator.baseInstaller.install(ctx, file)
fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus) 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)
fuzzBin.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Corpus)
builder := android.NewRuleBuilder(pctx, ctx) builder := android.NewRuleBuilder(pctx, ctx)
intermediateDir := android.PathForModuleOut(ctx, "corpus") intermediateDir := android.PathForModuleOut(ctx, "corpus")
for _, entry := range fuzz.fuzzPackagedModule.Corpus { for _, entry := range fuzzBin.fuzzPackagedModule.Corpus {
builder.Command().Text("cp"). builder.Command().Text("cp").
Input(entry). Input(entry).
Output(intermediateDir.Join(ctx, entry.Base())) Output(intermediateDir.Join(ctx, entry.Base()))
} }
builder.Build("copy_corpus", "copy corpus") 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) builder = android.NewRuleBuilder(pctx, ctx)
intermediateDir = android.PathForModuleOut(ctx, "data") intermediateDir = android.PathForModuleOut(ctx, "data")
for _, entry := range fuzz.fuzzPackagedModule.Data { for _, entry := range fuzzBin.fuzzPackagedModule.Data {
builder.Command().Text("cp"). builder.Command().Text("cp").
Input(entry). Input(entry).
Output(intermediateDir.Join(ctx, entry.Rel())) Output(intermediateDir.Join(ctx, entry.Rel()))
} }
builder.Build("copy_data", "copy data") builder.Build("copy_data", "copy data")
fuzz.fuzzPackagedModule.DataIntermediateDir = intermediateDir fuzzBin.fuzzPackagedModule.DataIntermediateDir = intermediateDir
if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil { if fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary) fuzzBin.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary)
if fuzz.fuzzPackagedModule.Dictionary.Ext() != ".dict" { if fuzzBin.fuzzPackagedModule.Dictionary.Ext() != ".dict" {
ctx.PropertyErrorf("dictionary", ctx.PropertyErrorf("dictionary",
"Fuzzer dictionary %q does not have '.dict' extension", "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") configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
android.WriteFileRule(ctx, configPath, fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config.String()) android.WriteFileRule(ctx, configPath, fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
fuzz.fuzzPackagedModule.Config = configPath fuzzBin.fuzzPackagedModule.Config = configPath
} }
// Grab the list of required shared libraries. // Grab the list of required shared libraries.
@@ -225,31 +321,36 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) {
}) })
for _, lib := range sharedLibraries { for _, lib := range sharedLibraries {
fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
sharedLibraryInstallLocation( 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. // Also add the dependency on the shared library symbols dir.
if !ctx.Host() { if !ctx.Host() {
fuzz.installedSharedDeps = append(fuzz.installedSharedDeps, fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
sharedLibrarySymbolsInstallLocation(lib, ctx.Arch().ArchType.String())) 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) 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) module.sanitize.SetSanitizer(Fuzzer, true)
fuzz := &fuzzBinary{ fuzzBin := &fuzzBinary{
binaryDecorator: binary, binaryDecorator: binary,
baseCompiler: NewBaseCompiler(), baseCompiler: NewBaseCompiler(),
fuzzType: fuzzType,
} }
module.compiler = fuzz module.compiler = fuzzBin
module.linker = fuzz module.linker = fuzzBin
module.installer = fuzz module.installer = fuzzBin
// The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin. // The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin.
android.AddLoadHook(module, func(ctx android.LoadHookContext) { android.AddLoadHook(module, func(ctx android.LoadHookContext) {
@@ -268,6 +369,17 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module {
ctx.AppendProperties(&disableDarwinAndLinuxBionic) 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 return module
} }
@@ -275,10 +387,30 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module {
// their architecture & target/host specific zip file. // their architecture & target/host specific zip file.
type ccFuzzPackager struct { type ccFuzzPackager struct {
fuzz.FuzzPackager fuzz.FuzzPackager
fuzzPackagingArchModules string
fuzzTargetSharedDepsInstallPairs string
allFuzzTargetsName string
} }
func fuzzPackagingFactory() android.Singleton { 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) { func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
@@ -306,8 +438,9 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
return return
} }
sharedLibsInstallDirPrefix := "lib"
fuzzModule, ok := ccModule.compiler.(*fuzzBinary) fuzzModule, ok := ccModule.compiler.(*fuzzBinary)
if !ok { if !ok || fuzzModule.fuzzType != s.FuzzType {
return return
} }
@@ -316,8 +449,18 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
hostOrTargetString = "host" 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() 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()} archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
// Grab the list of required shared libraries. // Grab the list of required shared libraries.
@@ -327,22 +470,21 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
builder := android.NewRuleBuilder(pctx, ctx) builder := android.NewRuleBuilder(pctx, ctx)
// Package the corpus, data, dict and config into a zipfile. // 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 // 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. // The executable.
files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""}) 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 { if !ok {
return return
} }
}) })
s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx) s.CreateFuzzPackage(ctx, archDirs, s.FuzzType, pctx)
} }
func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) { func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
@@ -353,27 +495,34 @@ func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
// ready to handle phony targets created in Soong. In the meantime, this // ready to handle phony targets created in Soong. In the meantime, this
// exports the phony 'fuzz' target and dependencies on packages to // exports the phony 'fuzz' target and dependencies on packages to
// core/main.mk so that we can use dist-for-goals. // 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, " ")) strings.Join(s.FuzzPackager.SharedLibInstallStrings, " "))
// Preallocate the slice of fuzz targets to minimise memory allocations. // 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 // GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for
// packaging. // 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 var files []fuzz.FileToZip
fuzzDir := "fuzz"
if s.FuzzType == fuzz.AFL {
fuzzDir = "afl_fuzz"
}
for _, library := range sharedLibraries { 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 // For each architecture-specific shared library dependency, we need to
// install it to the output directory. Setup the install destination here, // install it to the output directory. Setup the install destination here,
// which will be used by $(copy-many-files) in the Make backend. // which will be used by $(copy-many-files) in the Make backend.
installDestination := sharedLibraryInstallLocation( installDestination := sharedLibraryInstallLocation(
library, module.Host(), archString) library, module.Host(), fuzzDir, archString)
if (*sharedLibraryInstalled)[installDestination] { if (*sharedLibraryInstalled)[installDestination] {
continue continue
} }
@@ -391,7 +540,7 @@ func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface,
// we want symbolization tools (like `stack`) to be able to find the symbols // we want symbolization tools (like `stack`) to be able to find the symbols
// in $ANDROID_PRODUCT_OUT/symbols automagically. // in $ANDROID_PRODUCT_OUT/symbols automagically.
if !module.Host() { if !module.Host() {
symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString) symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, fuzzDir, archString)
symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$") symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
s.SharedLibInstallStrings = append(s.SharedLibInstallStrings, s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
library.String()+":"+symbolsInstallDestination) library.String()+":"+symbolsInstallDestination)

View File

@@ -534,7 +534,8 @@ var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers(
android.PrepareForTestWithAndroidBuildComponents, android.PrepareForTestWithAndroidBuildComponents,
android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest), android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 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", TestFactory)
ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
@@ -648,7 +649,8 @@ func TestConfig(buildDir string, os android.OsType, env map[string]string,
func CreateTestContext(config android.Config) *android.TestContext { func CreateTestContext(config android.Config) *android.TestContext {
ctx := android.NewTestArchContext(config) ctx := android.NewTestArchContext(config)
genrule.RegisterGenruleBuildComponents(ctx) 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", TestFactory)
ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory)

View File

@@ -26,12 +26,13 @@ import (
"android/soong/android" "android/soong/android"
) )
type Lang string type FuzzType string
const ( const (
Cc Lang = "" Cc FuzzType = ""
Rust Lang = "rust" Rust FuzzType = "rust"
Java Lang = "java" Java FuzzType = "java"
AFL FuzzType = "AFL"
) )
var BoolDefault = proptools.BoolDefault var BoolDefault = proptools.BoolDefault
@@ -46,6 +47,7 @@ type FuzzPackager struct {
Packages android.Paths Packages android.Paths
FuzzTargets map[string]bool FuzzTargets map[string]bool
SharedLibInstallStrings []string SharedLibInstallStrings []string
FuzzType FuzzType
} }
type FileToZip struct { type FileToZip struct {
@@ -208,7 +210,7 @@ func (f *FuzzConfig) String() string {
return string(b) 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 var archOsList []ArchOs
for archOs := range archDirs { for archOs := range archDirs {
archOsList = append(archOsList, archOs) archOsList = append(archOsList, archOs)
@@ -221,12 +223,15 @@ func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs
hostOrTarget := archOs.HostOrTarget hostOrTarget := archOs.HostOrTarget
builder := android.NewRuleBuilder(pctx, ctx) builder := android.NewRuleBuilder(pctx, ctx)
zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip" zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip"
if lang == Rust { if fuzzType == Rust {
zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip" zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip"
} }
if lang == Java { if fuzzType == Java {
zipFileName = "fuzz-java-" + hostOrTarget + "-" + arch + ".zip" zipFileName = "fuzz-java-" + hostOrTarget + "-" + arch + ".zip"
} }
if fuzzType == AFL {
zipFileName = "fuzz-afl-" + hostOrTarget + "-" + arch + ".zip"
}
outputFile := android.PathForOutput(ctx, zipFileName) outputFile := android.PathForOutput(ctx, zipFileName)
s.Packages = append(s.Packages, outputFile) s.Packages = append(s.Packages, outputFile)
@@ -237,7 +242,6 @@ func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs
Flag("-L 0") // No need to try and re-compress the zipfiles. Flag("-L 0") // No need to try and re-compress the zipfiles.
for _, fileToZip := range filesToZip { for _, fileToZip := range filesToZip {
if fileToZip.DestinationPathPrefix != "" { if fileToZip.DestinationPathPrefix != "" {
command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
} else { } else {
@@ -256,6 +260,7 @@ func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets str
for target, _ := range s.FuzzTargets { for target, _ := range s.FuzzTargets {
fuzzTargets = append(fuzzTargets, target) fuzzTargets = append(fuzzTargets, target)
} }
sort.Strings(fuzzTargets) sort.Strings(fuzzTargets)
ctx.Strict(targets, strings.Join(fuzzTargets, " ")) ctx.Strict(targets, strings.Join(fuzzTargets, " "))
} }

View File

@@ -153,7 +153,7 @@ func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, cc.UnstrippedOutputFile, cc.IsValidSharedDependency) sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, cc.UnstrippedOutputFile, cc.IsValidSharedDependency)
// Package shared libraries // Package shared libraries
files = append(files, cc.GetSharedLibsToZip(sharedLibraries, rustModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...) files = append(files, cc.GetSharedLibsToZip(sharedLibraries, rustModule, &s.FuzzPackager, archString, "lib", &sharedLibraryInstalled)...)
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok { if !ok {