Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fdf043a7 authored by Cory Barker's avatar Cory Barker
Browse files

Fix Soong code, remove dead code, and clean up code for Java fuzz

Test: built fuzz targets locally and tested them with Jazzer

Change-Id: I3ff487ba4e34289e0f53f2077463f524f4bf4f11
parent 55e1dbb7
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -133,13 +133,19 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
	return entriesList
}

func (j *JavaFuzzLibrary) AndroidMkEntries() []android.AndroidMkEntries {
func (j *JavaFuzzTest) AndroidMkEntries() []android.AndroidMkEntries {
	entriesList := j.Library.AndroidMkEntries()
	entries := &entriesList[0]
	entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
		entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", "null-suite")
		androidMkWriteTestData(j.jniFilePaths, entries)
		androidMkWriteTestData(android.Paths{j.implementationJarFile}, entries)
		androidMkWriteTestData(j.jniFilePaths, entries)
		if j.fuzzPackagedModule.Corpus != nil {
			androidMkWriteTestData(j.fuzzPackagedModule.Corpus, entries)
		}
		if j.fuzzPackagedModule.Dictionary != nil {
			androidMkWriteTestData(android.Paths{j.fuzzPackagedModule.Dictionary}, entries)
		}
	})
	return entriesList
}
+59 −147
Original line number Diff line number Diff line
@@ -19,12 +19,12 @@ import (
	"sort"
	"strings"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"

	"android/soong/android"
	"android/soong/cc"
	"android/soong/fuzz"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)

const (
@@ -32,63 +32,63 @@ const (
	targetString = "target"
)

type jniProperties struct {
	// list of jni libs
	Jni_libs []string

	// sanitization
	Sanitizers []string
}

func init() {
	RegisterJavaFuzzBuildComponents(android.InitRegistrationContext)
}

func RegisterJavaFuzzBuildComponents(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("java_fuzz", JavaFuzzFactory)
	ctx.RegisterModuleType("java_fuzz_host", JavaFuzzHostFactory)
	ctx.RegisterSingletonType("java_fuzz_host_packaging", javaFuzzHostPackagingFactory)
	ctx.RegisterSingletonType("java_fuzz_device_packaging", javaFuzzDevicePackagingFactory)
	ctx.RegisterSingletonType("java_fuzz_packaging", javaFuzzPackagingFactory)
}

type JavaFuzzLibrary struct {
	Library
type JavaFuzzTest struct {
	Test
	fuzzPackagedModule fuzz.FuzzPackagedModule
	jniProperties      jniProperties
	jniFilePaths       android.Paths
}

// IsSanitizerEnabledForJni implemented to make JavaFuzzLibrary implement
// cc.JniSanitizeable. It returns a bool for whether a cc dependency should be
// sanitized for the given sanitizer or not.
func (j *JavaFuzzLibrary) IsSanitizerEnabledForJni(ctx android.BaseModuleContext, sanitizerName string) bool {
	// TODO: once b/231370928 is resolved, please uncomment the loop
	//     for _, s := range j.jniProperties.Sanitizers {
	//         if sanitizerName == s {
	//             return true
	//         }
	//     }
	return false
// java_fuzz builds and links sources into a `.jar` file for the device.
// This generates .class files in a jar which can then be instrumented before
// fuzzing in Android Runtime (ART: Android OS on emulator or device)
func JavaFuzzFactory() android.Module {
	module := &JavaFuzzTest{}

	module.addHostAndDeviceProperties()
	module.AddProperties(&module.testProperties)
	module.AddProperties(&module.fuzzPackagedModule.FuzzProperties)

	module.Module.properties.Installable = proptools.BoolPtr(true)
	module.Module.dexpreopter.isTest = true
	module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)

	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
		disableLinuxBionic := struct {
			Target struct {
				Linux_bionic struct {
					Enabled *bool
				}
			}
		}{}
		disableLinuxBionic.Target.Linux_bionic.Enabled = proptools.BoolPtr(false)
		ctx.AppendProperties(&disableLinuxBionic)
	})

func (j *JavaFuzzLibrary) DepsMutator(mctx android.BottomUpMutatorContext) {
	if len(j.jniProperties.Jni_libs) > 0 {
		if j.fuzzPackagedModule.FuzzProperties.Fuzz_config == nil {
			config := &fuzz.FuzzConfig{}
			j.fuzzPackagedModule.FuzzProperties.Fuzz_config = config
	InitJavaModuleMultiTargets(module, android.HostAndDeviceSupported)
	return module
}
		// this will be used by the ingestion pipeline to determine the version
		// of jazzer to add to the fuzzer package
		j.fuzzPackagedModule.FuzzProperties.Fuzz_config.IsJni = proptools.BoolPtr(true)
		for _, target := range mctx.MultiTargets() {

func (j *JavaFuzzTest) DepsMutator(ctx android.BottomUpMutatorContext) {
	if len(j.testProperties.Jni_libs) > 0 {
		for _, target := range ctx.MultiTargets() {
			sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
			mctx.AddFarVariationDependencies(sharedLibVariations, cc.JniFuzzLibTag, j.jniProperties.Jni_libs...)
			ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...)
		}
	}
	j.Library.DepsMutator(mctx)

	j.deps(ctx)
}

func (j *JavaFuzzLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
func (j *JavaFuzzTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	if j.fuzzPackagedModule.FuzzProperties.Corpus != nil {
		j.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Corpus)
	}
@@ -105,21 +105,15 @@ func (j *JavaFuzzLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
	}

	_, sharedDeps := cc.CollectAllSharedDependencies(ctx)

	for _, dep := range sharedDeps {
		sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo)
		if sharedLibInfo.SharedLibrary != nil {
			// The .class jars are output in slightly different locations
			// relative to the jni libs. Therefore, for consistency across
			// host and device fuzzers of jni lib location, we save it in a
			// native_libs directory.
			var relPath string
			arch := "lib"
			if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" {
				relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base())
			} else {
				relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base())
				arch = "lib64"
			}
			libPath := android.PathForModuleOut(ctx, relPath)

			libPath := android.PathForModuleOut(ctx, filepath.Join(arch, sharedLibInfo.SharedLibrary.Base()))
			ctx.Build(pctx, android.BuildParams{
				Rule:   android.Cp,
				Input:  sharedLibInfo.SharedLibrary,
@@ -129,104 +123,35 @@ func (j *JavaFuzzLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
		} else {
			ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
		}
	}

	j.Library.GenerateAndroidBuildActions(ctx)
	}

// java_fuzz_host builds and links sources into a `.jar` file for the host.
//
// By default, a java_fuzz produces a `.jar` file containing `.class` files.
// This jar is not suitable for installing on a device.
func JavaFuzzHostFactory() android.Module {
	module := &JavaFuzzLibrary{}
	module.addHostProperties()
	module.AddProperties(&module.jniProperties)
	module.Module.properties.Installable = proptools.BoolPtr(true)
	module.AddProperties(&module.fuzzPackagedModule.FuzzProperties)

	// java_fuzz packaging rules collide when both linux_glibc and linux_bionic are enabled, disable the linux_bionic variants.
	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
		disableLinuxBionic := struct {
			Target struct {
				Linux_bionic struct {
					Enabled *bool
				}
			}
		}{}
		disableLinuxBionic.Target.Linux_bionic.Enabled = proptools.BoolPtr(false)
		ctx.AppendProperties(&disableLinuxBionic)
	})

	InitJavaModuleMultiTargets(module, android.HostSupportedNoCross)
	return module
	j.Test.GenerateAndroidBuildActions(ctx)
}

// java_fuzz builds and links sources into a `.jar` file for the device.
// This generates .class files in a jar which can then be instrumented before
// fuzzing in Android Runtime (ART: Android OS on emulator or device)
func JavaFuzzFactory() android.Module {
	module := &JavaFuzzLibrary{}
	module.addHostAndDeviceProperties()
	module.AddProperties(&module.jniProperties)
	module.Module.properties.Installable = proptools.BoolPtr(true)
	module.AddProperties(&module.fuzzPackagedModule.FuzzProperties)
	module.Module.dexpreopter.isTest = true
	module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
	InitJavaModuleMultiTargets(module, android.DeviceSupported)
	return module
}

// Responsible for generating rules that package host fuzz targets into
// a zip file.
type javaFuzzHostPackager struct {
type javaFuzzPackager struct {
	fuzz.FuzzPackager
}

// Responsible for generating rules that package device fuzz targets into
// a zip file.
type javaFuzzDevicePackager struct {
	fuzz.FuzzPackager
func javaFuzzPackagingFactory() android.Singleton {
	return &javaFuzzPackager{}
}

func javaFuzzHostPackagingFactory() android.Singleton {
	return &javaFuzzHostPackager{}
}

func javaFuzzDevicePackagingFactory() android.Singleton {
	return &javaFuzzDevicePackager{}
}

func (s *javaFuzzHostPackager) GenerateBuildActions(ctx android.SingletonContext) {
	generateBuildActions(&s.FuzzPackager, hostString, ctx)
}

func (s *javaFuzzDevicePackager) GenerateBuildActions(ctx android.SingletonContext) {
	generateBuildActions(&s.FuzzPackager, targetString, ctx)
}

func generateBuildActions(s *fuzz.FuzzPackager, hostOrTargetString string, ctx android.SingletonContext) {
func (s *javaFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
	// Map between each architecture + host/device combination.
	archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)

	// List of individual fuzz targets.
	s.FuzzTargets = make(map[string]bool)

	ctx.VisitAllModules(func(module android.Module) {
		// Discard non-fuzz targets.
		javaFuzzModule, ok := module.(*JavaFuzzLibrary)
		javaFuzzModule, ok := module.(*JavaFuzzTest)
		if !ok {
			return
		}

		if hostOrTargetString == hostString {
			if !javaFuzzModule.Host() {
				return
			}
		} else if hostOrTargetString == targetString {
			if javaFuzzModule.Host() || javaFuzzModule.Target().HostCross {
				return
			}
		hostOrTargetString := "target"
		if javaFuzzModule.Host() {
			hostOrTargetString = "host"
		}

		fuzzModuleValidator := fuzz.FuzzModule{
@@ -246,7 +171,7 @@ func generateBuildActions(s *fuzz.FuzzPackager, hostOrTargetString string, ctx a
		var files []fuzz.FileToZip
		builder := android.NewRuleBuilder(pctx, ctx)

		// Package the artifacts (data, corpus, config and dictionary into a zipfile.
		// Package the artifacts (data, corpus, config and dictionary) into a zipfile.
		files = s.PackageArtifacts(ctx, module, javaFuzzModule.fuzzPackagedModule, archDir, builder)

		// Add .jar
@@ -261,27 +186,14 @@ func generateBuildActions(s *fuzz.FuzzPackager, hostOrTargetString string, ctx a
		if !ok {
			return
		}

	})
	s.CreateFuzzPackage(ctx, archDirs, fuzz.Java, pctx)
}

func (s *javaFuzzHostPackager) MakeVars(ctx android.MakeVarsContext) {
func (s *javaFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
	packages := s.Packages.Strings()
	sort.Strings(packages)

	ctx.Strict("SOONG_JAVA_FUZZ_HOST_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))

	// Preallocate the slice of fuzz targets to minimize memory allocations.
	s.PreallocateSlice(ctx, "ALL_JAVA_FUZZ_HOST_TARGETS")
}

func (s *javaFuzzDevicePackager) MakeVars(ctx android.MakeVarsContext) {
	packages := s.Packages.Strings()
	sort.Strings(packages)

	ctx.Strict("SOONG_JAVA_FUZZ_DEVICE_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))

	ctx.Strict("SOONG_JAVA_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
	// Preallocate the slice of fuzz targets to minimize memory allocations.
	s.PreallocateSlice(ctx, "ALL_JAVA_FUZZ_DEVICE_TARGETS")
	s.PreallocateSlice(ctx, "ALL_JAVA_FUZZ_TARGETS")
}
+4 −6
Original line number Diff line number Diff line
@@ -31,17 +31,15 @@ var prepForJavaFuzzTest = android.GroupFixturePreparers(

func TestJavaFuzz(t *testing.T) {
	result := prepForJavaFuzzTest.RunTestWithBp(t, `
		java_fuzz_host {
		java_fuzz {
			name: "foo",
			srcs: ["a.java"],
			host_supported: true,
			device_supported: false,
			libs: ["bar"],
			static_libs: ["baz"],
            jni_libs: [
                "libjni",
            ],
            sanitizers: [
                "address",
                "fuzzer",
            ],
		}

@@ -84,7 +82,7 @@ func TestJavaFuzz(t *testing.T) {
	}

	ctx := result.TestContext
	foo := ctx.ModuleForTests("foo", osCommonTarget).Module().(*JavaFuzzLibrary)
	foo := ctx.ModuleForTests("foo", osCommonTarget).Module().(*JavaFuzzTest)

	expected := "lib64/libjni.so"
	if runtime.GOOS == "darwin" {
+0 −1
Original line number Diff line number Diff line
@@ -1144,7 +1144,6 @@ func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
	}

	j.addDataDeviceBinsDeps(ctx)

	j.deps(ctx)
}