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

Commit 28cbb75a authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "disable mixed builds for sanitized cc modules"

parents aea50670 ef69d47d
Loading
Loading
Loading
Loading
+35 −6
Original line number Diff line number Diff line
@@ -1893,17 +1893,46 @@ func (c *Module) QueueBazelCall(ctx android.BaseModuleContext) {
// IsMixedBuildSupported returns true if the module should be analyzed by Bazel
// in any of the --bazel-mode(s).
func (c *Module) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
	// TODO(b/261058727): Remove this (enable mixed builds for modules with UBSan)
	// Currently we can only support ubsan when minimum runtime is used.
	return c.bazelHandler != nil && (!isUbsanEnabled(c) || c.MinimalRuntimeNeeded())
	if !allEnabledSanitizersSupportedByBazel(c) {
		//TODO(b/278772861) support sanitizers in Bazel rules
		return false
	}
	return c.bazelHandler != nil
}

func isUbsanEnabled(c *Module) bool {
func allEnabledSanitizersSupportedByBazel(c *Module) bool {
	if c.sanitize == nil {
		return false
		return true
	}
	sanitizeProps := &c.sanitize.Properties.SanitizeMutated
	return Bool(sanitizeProps.Integer_overflow) || len(sanitizeProps.Misc_undefined) > 0

	unsupportedSanitizers := []*bool{
		sanitizeProps.Safestack,
		sanitizeProps.Cfi,
		sanitizeProps.Scudo,
		BoolPtr(len(c.sanitize.Properties.Sanitize.Recover) > 0),
		BoolPtr(c.sanitize.Properties.Sanitize.Blocklist != nil),
	}
	for _, san := range unsupportedSanitizers {
		if Bool(san) {
			return false
		}
	}

	for _, san := range Sanitizers {
		if san == intOverflow {
			// TODO(b/261058727): enable mixed builds for all modules with UBSan
			// Currently we can only support ubsan when minimum runtime is used.
			ubsanEnabled := Bool(sanitizeProps.Integer_overflow) || len(sanitizeProps.Misc_undefined) > 0
			if ubsanEnabled && !c.MinimalRuntimeNeeded() {
				return false
			}
		} else if c.sanitize.isSanitizerEnabled(san) {
			return false
		}
	}

	return true
}

func GetApexConfigKey(ctx android.BaseModuleContext) *android.ApexConfigKey {
+258 −0
Original line number Diff line number Diff line
@@ -3114,6 +3114,11 @@ func TestLibDepAndroidMkExportInMixedBuilds(t *testing.T) {
			whole_static_libs: ["whole_static_dep"],
			shared_libs: ["shared_dep"],
			gtest: false,
			sanitize: {
				// cc_test modules default to memtag_heap: true,
				// but this adds extra dependencies that we don't care about
				never: true,
			}
		}
		cc_binary {
			name: "binary",
@@ -5101,3 +5106,256 @@ func TestDclaLibraryInApex(t *testing.T) {
	expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.so"}
	android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
}

func TestDisableSanitizerVariantsInMixedBuilds(t *testing.T) {
	t.Parallel()
	bp := `
		cc_library_static {
			name: "foo_ubsan_minimal",
			srcs: ["foo.cc"],
			bazel_module: { label: "//foo_ubsan_minimal" },
			sanitize: {
				all_undefined: true,
				integer_overflow: true,
			},
		}
		cc_library_static {
			name: "foo",
			srcs: ["foo.cc"],
			bazel_module: { label: "//foo" },
			sanitize: {
				address: true,
				hwaddress: true,
				fuzzer: true,
				integer_overflow: true,
				scs: true,
			},
		}
		cc_library_static {
			name: "foo_tsan",
			srcs: ["foo.cc"],
			bazel_module: { label: "//foo_tsan" },
			sanitize: {
				thread: true,
			},
		}
		cc_library_static {
			name: "foo_cfi",
			srcs: ["foo.cc"],
			bazel_module: { label: "//foo_cfi" },
			sanitize: {
				cfi: true,
			},
		}
		cc_library_static {
			name: "foo_memtag_stack",
			srcs: ["foo.cc"],
			bazel_module: { label: "//foo_memtag_stack" },
			sanitize: {
				memtag_stack: true,
			},
		}
		cc_library_static {
			name: "foo_memtag_heap",
			srcs: ["foo.cc"],
			bazel_module: { label: "//foo_memtag_heap" },
			sanitize: {
				memtag_heap: true,
			},
		}
		cc_library_static {
			name: "foo_safestack",
			srcs: ["foo.cc"],
			bazel_module: { label: "//foo_safestack" },
			sanitize: {
				safestack: true,
			},
		}
		cc_library_static {
			name: "foo_scudo",
			srcs: ["foo.cc"],
			bazel_module: { label: "//foo_scudo" },
			sanitize: {
				scudo: true,
			},
		}
	`
	testcases := []struct {
		name                string
		variant             string
		expectedOutputPaths []string
	}{
		{
			name:    "foo_ubsan_minimal",
			variant: "android_arm64_armv8-a_static_apex28",
			expectedOutputPaths: []string{
				"outputbase/execroot/__main__/foo_ubsan_minimal.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm64_armv8-a_static_apex28",
			expectedOutputPaths: []string{
				"outputbase/execroot/__main__/foo.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm_armv7-a-neon_static_asan_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo/android_arm_armv7-a-neon_static_asan_apex28/foo.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm64_armv8-a_static_hwasan_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo/android_arm64_armv8-a_static_hwasan_apex28/foo.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm64_armv8-a_static_fuzzer_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo/android_arm64_armv8-a_static_fuzzer_apex28/foo.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm_armv7-a-neon_static_asan_fuzzer_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo/android_arm_armv7-a-neon_static_asan_fuzzer_apex28/foo.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm64_armv8-a_static_hwasan_fuzzer_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo/android_arm64_armv8-a_static_hwasan_fuzzer_apex28/foo.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm64_armv8-a_static_scs_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo/android_arm64_armv8-a_static_scs_apex28/foo.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm64_armv8-a_static_hwasan_scs_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo/android_arm64_armv8-a_static_hwasan_scs_apex28/foo.a",
			},
		},
		{
			name:    "foo",
			variant: "android_arm64_armv8-a_static_hwasan_scs_fuzzer_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo/android_arm64_armv8-a_static_hwasan_scs_fuzzer_apex28/foo.a",
			},
		},
		{
			name:    "foo_tsan",
			variant: "android_arm64_armv8-a_static_apex28",
			expectedOutputPaths: []string{
				"outputbase/execroot/__main__/foo_tsan.a",
			},
		},
		{
			name:    "foo_tsan",
			variant: "android_arm64_armv8-a_static_tsan_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo_tsan/android_arm64_armv8-a_static_tsan_apex28/foo_tsan.a",
			},
		},
		{
			name:    "foo_cfi",
			variant: "android_arm64_armv8-a_static_apex28",
			expectedOutputPaths: []string{
				"outputbase/execroot/__main__/foo_cfi.a",
			},
		},
		{
			name:    "foo_cfi",
			variant: "android_arm64_armv8-a_static_cfi_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo_cfi/android_arm64_armv8-a_static_cfi_apex28/foo_cfi.a",
			},
		},
		{
			name:    "foo_memtag_stack",
			variant: "android_arm64_armv8-a_static_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo_memtag_stack/android_arm64_armv8-a_static_apex28/foo_memtag_stack.a",
			},
		},
		{
			name:    "foo_memtag_heap",
			variant: "android_arm64_armv8-a_static_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo_memtag_heap/android_arm64_armv8-a_static_apex28/foo_memtag_heap.a",
			},
		},
		{
			name:    "foo_safestack",
			variant: "android_arm64_armv8-a_static_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo_safestack/android_arm64_armv8-a_static_apex28/foo_safestack.a",
			},
		},
		{
			name:    "foo_scudo",
			variant: "android_arm64_armv8-a_static_apex28",
			expectedOutputPaths: []string{
				"out/soong/.intermediates/foo_scudo/android_arm64_armv8-a_static_apex28/foo_scudo.a",
			},
		},
	}

	ctx := android.GroupFixturePreparers(
		prepareForCcTest,
		prepareForAsanTest,
		android.FixtureRegisterWithContext(registerTestMutators),
		android.FixtureModifyConfig(func(config android.Config) {
			config.BazelContext = android.MockBazelContext{
				OutputBaseDir: "outputbase",
				LabelToCcInfo: map[string]cquery.CcInfo{
					"//foo_ubsan_minimal": {
						RootStaticArchives: []string{"foo_ubsan_minimal.a"},
					},
					"//foo": {
						RootStaticArchives: []string{"foo.a"},
					},
					"//foo_tsan": {
						RootStaticArchives: []string{"foo_tsan.a"},
					},
					"//foo_cfi": {
						RootStaticArchives: []string{"foo_cfi.a"},
					},
					"//foo_memtag_stack": {
						RootStaticArchives: []string{"INVALID_ARCHIVE.a"},
					},
					"//foo_memtag_heap": {
						RootStaticArchives: []string{"INVALID_ARCHIVE.a"},
					},
					"//foo_safestack": {
						RootStaticArchives: []string{"INVALID_ARCHIVE.a"},
					},
					"//foo_scudo": {
						RootStaticArchives: []string{"INVALID_ARCHIVE.a"},
					},
				},
			}
		}),
	).RunTestWithBp(t, bp).TestContext

	for _, tc := range testcases {
		fooMod := ctx.ModuleForTests(tc.name, tc.variant).Module()
		outputFiles, err := fooMod.(android.OutputFileProducer).OutputFiles("")
		if err != nil {
			t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
		}
		android.AssertPathsRelativeToTopEquals(t, "output files", tc.expectedOutputPaths, outputFiles)
	}
}