Merge "disable mixed builds for sanitized cc modules"

This commit is contained in:
Treehugger Robot
2023-04-24 20:12:34 +00:00
committed by Gerrit Code Review
2 changed files with 295 additions and 8 deletions

View File

@@ -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())
}
func isUbsanEnabled(c *Module) bool {
if c.sanitize == nil {
if !allEnabledSanitizersSupportedByBazel(c) {
//TODO(b/278772861) support sanitizers in Bazel rules
return false
}
return c.bazelHandler != nil
}
func allEnabledSanitizersSupportedByBazel(c *Module) bool {
if c.sanitize == nil {
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 {

View File

@@ -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)
}
}