Limit propagating san config of shared to fuzzer
Prior to refactoring the sanitizers to use transition mutators, only
fuzzer sanitizer propagated configuration to shared dependencies
https://android-review.googlesource.com/c/platform/build/soong/+/2123434/9/cc/sanitize.go#b1365
However, this expanded to include TSAN in the refactoring
https://android-review.googlesource.com/c/platform/build/soong/+/2123434/9/cc/sanitize.go#1068.
Fortunately, TSAN is never enabled via Android.bp files in AOSP, so
there was no regression, but we should restore to the prevous state.
Test: go tests
Change-Id: I1a5ad8d033f7a9b4f7578393a2eac7c9362ab6f7
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 2393f3e..a449a98 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -29,6 +29,56 @@
}
`))
+var prepareForTsanTest = android.FixtureAddFile("tsan/Android.bp", []byte(`
+ cc_library_shared {
+ name: "libclang_rt.tsan",
+ }
+`))
+
+// expectSharedLinkDep verifies that the from module links against the to module as a
+// shared library.
+func expectSharedLinkDep(t *testing.T, from, to android.TestingModule) {
+ t.Helper()
+ fromLink := from.Description("link")
+ toLink := to.Description("strip")
+
+ if g, w := fromLink.OrderOnly.Strings(), toLink.Output.String(); !android.InList(w, g) {
+ t.Errorf("%s should link against %s, expected %q, got %q",
+ from.Module(), to.Module(), w, g)
+ }
+}
+
+// expectStaticLinkDep verifies that the from module links against the to module as a
+// static library.
+func expectStaticLinkDep(t *testing.T, from, to android.TestingModule) {
+ t.Helper()
+ fromLink := from.Description("link")
+ toLink := to.Description("static link")
+
+ if g, w := fromLink.Implicits.Strings(), toLink.Output.String(); !android.InList(w, g) {
+ t.Errorf("%s should link against %s, expected %q, got %q",
+ from.Module(), to.Module(), w, g)
+ }
+
+}
+
+// expectInstallDep verifies that the install rule of the from module depends on the
+// install rule of the to module.
+func expectInstallDep(t *testing.T, from, to android.TestingModule) {
+ t.Helper()
+ fromInstalled := from.Description("install")
+ toInstalled := to.Description("install")
+
+ // combine implicits and order-only dependencies, host uses implicit but device uses
+ // order-only.
+ got := append(fromInstalled.Implicits.Strings(), fromInstalled.OrderOnly.Strings()...)
+ want := toInstalled.Output.String()
+ if !android.InList(want, got) {
+ t.Errorf("%s installation should depend on %s, expected %q, got %q",
+ from.Module(), to.Module(), want, got)
+ }
+}
+
func TestAsan(t *testing.T) {
bp := `
cc_binary {
@@ -140,85 +190,254 @@
libStaticAsan := result.ModuleForTests("libstatic_asan", staticAsanVariant)
libStaticAsanNoAsanVariant := result.ModuleForTests("libstatic_asan", staticVariant)
- // expectSharedLinkDep verifies that the from module links against the to module as a
- // shared library.
- expectSharedLinkDep := func(from, to android.TestingModule) {
- t.Helper()
- fromLink := from.Description("link")
- toLink := to.Description("strip")
+ expectSharedLinkDep(t, binWithAsan, libShared)
+ expectSharedLinkDep(t, binWithAsan, libAsan)
+ expectSharedLinkDep(t, libShared, libTransitive)
+ expectSharedLinkDep(t, libAsan, libTransitive)
- if g, w := fromLink.OrderOnly.Strings(), toLink.Output.String(); !android.InList(w, g) {
- t.Errorf("%s should link against %s, expected %q, got %q",
- from.Module(), to.Module(), w, g)
- }
- }
+ expectStaticLinkDep(t, binWithAsan, libStaticAsanVariant)
+ expectStaticLinkDep(t, binWithAsan, libNoAsan)
+ expectStaticLinkDep(t, binWithAsan, libStaticAsan)
- // expectStaticLinkDep verifies that the from module links against the to module as a
- // static library.
- expectStaticLinkDep := func(from, to android.TestingModule) {
- t.Helper()
- fromLink := from.Description("link")
- toLink := to.Description("static link")
+ expectInstallDep(t, binWithAsan, libShared)
+ expectInstallDep(t, binWithAsan, libAsan)
+ expectInstallDep(t, binWithAsan, libTransitive)
+ expectInstallDep(t, libShared, libTransitive)
+ expectInstallDep(t, libAsan, libTransitive)
- if g, w := fromLink.Implicits.Strings(), toLink.Output.String(); !android.InList(w, g) {
- t.Errorf("%s should link against %s, expected %q, got %q",
- from.Module(), to.Module(), w, g)
- }
+ expectSharedLinkDep(t, binNoAsan, libShared)
+ expectSharedLinkDep(t, binNoAsan, libAsan)
+ expectSharedLinkDep(t, libShared, libTransitive)
+ expectSharedLinkDep(t, libAsan, libTransitive)
- }
+ expectStaticLinkDep(t, binNoAsan, libStaticNoAsanVariant)
+ expectStaticLinkDep(t, binNoAsan, libNoAsan)
+ expectStaticLinkDep(t, binNoAsan, libStaticAsanNoAsanVariant)
- // expectInstallDep verifies that the install rule of the from module depends on the
- // install rule of the to module.
- expectInstallDep := func(from, to android.TestingModule) {
- t.Helper()
- fromInstalled := from.Description("install")
- toInstalled := to.Description("install")
-
- // combine implicits and order-only dependencies, host uses implicit but device uses
- // order-only.
- got := append(fromInstalled.Implicits.Strings(), fromInstalled.OrderOnly.Strings()...)
- want := toInstalled.Output.String()
- if !android.InList(want, got) {
- t.Errorf("%s installation should depend on %s, expected %q, got %q",
- from.Module(), to.Module(), want, got)
- }
- }
-
- expectSharedLinkDep(binWithAsan, libShared)
- expectSharedLinkDep(binWithAsan, libAsan)
- expectSharedLinkDep(libShared, libTransitive)
- expectSharedLinkDep(libAsan, libTransitive)
-
- expectStaticLinkDep(binWithAsan, libStaticAsanVariant)
- expectStaticLinkDep(binWithAsan, libNoAsan)
- expectStaticLinkDep(binWithAsan, libStaticAsan)
-
- expectInstallDep(binWithAsan, libShared)
- expectInstallDep(binWithAsan, libAsan)
- expectInstallDep(binWithAsan, libTransitive)
- expectInstallDep(libShared, libTransitive)
- expectInstallDep(libAsan, libTransitive)
-
- expectSharedLinkDep(binNoAsan, libShared)
- expectSharedLinkDep(binNoAsan, libAsan)
- expectSharedLinkDep(libShared, libTransitive)
- expectSharedLinkDep(libAsan, libTransitive)
-
- expectStaticLinkDep(binNoAsan, libStaticNoAsanVariant)
- expectStaticLinkDep(binNoAsan, libNoAsan)
- expectStaticLinkDep(binNoAsan, libStaticAsanNoAsanVariant)
-
- expectInstallDep(binNoAsan, libShared)
- expectInstallDep(binNoAsan, libAsan)
- expectInstallDep(binNoAsan, libTransitive)
- expectInstallDep(libShared, libTransitive)
- expectInstallDep(libAsan, libTransitive)
+ expectInstallDep(t, binNoAsan, libShared)
+ expectInstallDep(t, binNoAsan, libAsan)
+ expectInstallDep(t, binNoAsan, libTransitive)
+ expectInstallDep(t, libShared, libTransitive)
+ expectInstallDep(t, libAsan, libTransitive)
}
t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) })
t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
}
+func TestTsan(t *testing.T) {
+ bp := `
+ cc_binary {
+ name: "bin_with_tsan",
+ host_supported: true,
+ shared_libs: [
+ "libshared",
+ "libtsan",
+ ],
+ sanitize: {
+ thread: true,
+ }
+ }
+
+ cc_binary {
+ name: "bin_no_tsan",
+ host_supported: true,
+ shared_libs: [
+ "libshared",
+ "libtsan",
+ ],
+ }
+
+ cc_library_shared {
+ name: "libshared",
+ host_supported: true,
+ shared_libs: ["libtransitive"],
+ }
+
+ cc_library_shared {
+ name: "libtsan",
+ host_supported: true,
+ shared_libs: ["libtransitive"],
+ sanitize: {
+ thread: true,
+ }
+ }
+
+ cc_library_shared {
+ name: "libtransitive",
+ host_supported: true,
+ }
+`
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ prepareForTsanTest,
+ ).RunTestWithBp(t, bp)
+
+ check := func(t *testing.T, result *android.TestResult, variant string) {
+ tsanVariant := variant + "_tsan"
+ sharedVariant := variant + "_shared"
+ sharedTsanVariant := sharedVariant + "_tsan"
+
+ // The binaries, one with tsan and one without
+ binWithTsan := result.ModuleForTests("bin_with_tsan", tsanVariant)
+ binNoTsan := result.ModuleForTests("bin_no_tsan", variant)
+
+ // Shared libraries that don't request tsan
+ libShared := result.ModuleForTests("libshared", sharedVariant)
+ libTransitive := result.ModuleForTests("libtransitive", sharedVariant)
+
+ // Shared library that requests tsan
+ libTsan := result.ModuleForTests("libtsan", sharedTsanVariant)
+
+ expectSharedLinkDep(t, binWithTsan, libShared)
+ expectSharedLinkDep(t, binWithTsan, libTsan)
+ expectSharedLinkDep(t, libShared, libTransitive)
+ expectSharedLinkDep(t, libTsan, libTransitive)
+
+ expectSharedLinkDep(t, binNoTsan, libShared)
+ expectSharedLinkDep(t, binNoTsan, libTsan)
+ expectSharedLinkDep(t, libShared, libTransitive)
+ expectSharedLinkDep(t, libTsan, libTransitive)
+ }
+
+ t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) })
+ t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
+}
+
+func TestFuzz(t *testing.T) {
+ bp := `
+ cc_binary {
+ name: "bin_with_fuzzer",
+ host_supported: true,
+ shared_libs: [
+ "libshared",
+ "libfuzzer",
+ ],
+ static_libs: [
+ "libstatic",
+ "libnofuzzer",
+ "libstatic_fuzzer",
+ ],
+ sanitize: {
+ fuzzer: true,
+ }
+ }
+
+ cc_binary {
+ name: "bin_no_fuzzer",
+ host_supported: true,
+ shared_libs: [
+ "libshared",
+ "libfuzzer",
+ ],
+ static_libs: [
+ "libstatic",
+ "libnofuzzer",
+ "libstatic_fuzzer",
+ ],
+ }
+
+ cc_library_shared {
+ name: "libshared",
+ host_supported: true,
+ shared_libs: ["libtransitive"],
+ }
+
+ cc_library_shared {
+ name: "libfuzzer",
+ host_supported: true,
+ shared_libs: ["libtransitive"],
+ sanitize: {
+ fuzzer: true,
+ }
+ }
+
+ cc_library_shared {
+ name: "libtransitive",
+ host_supported: true,
+ }
+
+ cc_library_static {
+ name: "libstatic",
+ host_supported: true,
+ }
+
+ cc_library_static {
+ name: "libnofuzzer",
+ host_supported: true,
+ sanitize: {
+ fuzzer: false,
+ }
+ }
+
+ cc_library_static {
+ name: "libstatic_fuzzer",
+ host_supported: true,
+ }
+
+ `
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ ).RunTestWithBp(t, bp)
+
+ check := func(t *testing.T, result *android.TestResult, variant string) {
+ fuzzerVariant := variant + "_fuzzer"
+ sharedVariant := variant + "_shared"
+ sharedFuzzerVariant := sharedVariant + "_fuzzer"
+ staticVariant := variant + "_static"
+ staticFuzzerVariant := staticVariant + "_fuzzer"
+
+ // The binaries, one with fuzzer and one without
+ binWithFuzzer := result.ModuleForTests("bin_with_fuzzer", fuzzerVariant)
+ binNoFuzzer := result.ModuleForTests("bin_no_fuzzer", variant)
+
+ // Shared libraries that don't request fuzzer
+ libShared := result.ModuleForTests("libshared", sharedVariant)
+ libTransitive := result.ModuleForTests("libtransitive", sharedVariant)
+
+ // Shared libraries that don't request fuzzer
+ libSharedFuzzer := result.ModuleForTests("libshared", sharedFuzzerVariant)
+ libTransitiveFuzzer := result.ModuleForTests("libtransitive", sharedFuzzerVariant)
+
+ // Shared library that requests fuzzer
+ libFuzzer := result.ModuleForTests("libfuzzer", sharedFuzzerVariant)
+
+ // Static library that uses an fuzzer variant for bin_with_fuzzer and a non-fuzzer variant
+ // for bin_no_fuzzer.
+ libStaticFuzzerVariant := result.ModuleForTests("libstatic", staticFuzzerVariant)
+ libStaticNoFuzzerVariant := result.ModuleForTests("libstatic", staticVariant)
+
+ // Static library that never uses fuzzer.
+ libNoFuzzer := result.ModuleForTests("libnofuzzer", staticVariant)
+
+ // Static library that specifies fuzzer
+ libStaticFuzzer := result.ModuleForTests("libstatic_fuzzer", staticFuzzerVariant)
+ libStaticFuzzerNoFuzzerVariant := result.ModuleForTests("libstatic_fuzzer", staticVariant)
+
+ expectSharedLinkDep(t, binWithFuzzer, libSharedFuzzer)
+ expectSharedLinkDep(t, binWithFuzzer, libFuzzer)
+ expectSharedLinkDep(t, libSharedFuzzer, libTransitiveFuzzer)
+ expectSharedLinkDep(t, libFuzzer, libTransitiveFuzzer)
+
+ expectStaticLinkDep(t, binWithFuzzer, libStaticFuzzerVariant)
+ expectStaticLinkDep(t, binWithFuzzer, libNoFuzzer)
+ expectStaticLinkDep(t, binWithFuzzer, libStaticFuzzer)
+
+ expectSharedLinkDep(t, binNoFuzzer, libShared)
+ expectSharedLinkDep(t, binNoFuzzer, libFuzzer)
+ expectSharedLinkDep(t, libShared, libTransitive)
+ expectSharedLinkDep(t, libFuzzer, libTransitiveFuzzer)
+
+ expectStaticLinkDep(t, binNoFuzzer, libStaticNoFuzzerVariant)
+ expectStaticLinkDep(t, binNoFuzzer, libNoFuzzer)
+ expectStaticLinkDep(t, binNoFuzzer, libStaticFuzzerNoFuzzerVariant)
+ }
+
+ t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
+}
+
func TestUbsan(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skip("requires linux")