From 7ece4aae36b7dc23b1b184c981eaf702c2486a08 Mon Sep 17 00:00:00 2001 From: Yu Liu Date: Fri, 25 Aug 2023 16:56:33 -0700 Subject: [PATCH] Support memtag sanitizer. Bug: 295173102 Test: local unit tests Change-Id: Ib8cd82cd3989d9c120255e149473d8ec00f100f5 --- bazel/configurability.go | 4 +- bp2build/cc_test_conversion_test.go | 223 ++++++++++++++++++++++++++++ cc/bp2build.go | 33 +++- cc/test.go | 15 ++ 4 files changed, 272 insertions(+), 3 deletions(-) diff --git a/bazel/configurability.go b/bazel/configurability.go index aa58fdc7e..1fe844219 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -39,7 +39,7 @@ const ( // Targets in arch.go osArchAndroidArm = "android_arm" - osArchAndroidArm64 = "android_arm64" + OsArchAndroidArm64 = "android_arm64" osArchAndroidRiscv64 = "android_riscv64" osArchAndroidX86 = "android_x86" osArchAndroidX86_64 = "android_x86_64" @@ -170,7 +170,7 @@ var ( platformOsArchMap = map[string]string{ osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm", - osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64", + OsArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64", osArchAndroidRiscv64: "//build/bazel/platforms/os_arch:android_riscv64", osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86", osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64", diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go index 76bbb5798..9639ab98f 100644 --- a/bp2build/cc_test_conversion_test.go +++ b/bp2build/cc_test_conversion_test.go @@ -139,6 +139,13 @@ cc_test_library { "host_without_device", "device", ]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, @@ -166,6 +173,13 @@ cc_test { "host_without_device", "device", ]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, @@ -197,6 +211,13 @@ cc_test { "host_without_device", "device", ]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, @@ -228,6 +249,13 @@ cc_test { ":libgtest", ]`, "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, @@ -260,6 +288,13 @@ cc_test { ":libgtest", ]`, "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, @@ -297,6 +332,13 @@ cc_test { "deps": `[":libgtest_isolated_main"]`, "dynamic_deps": `[":liblog"]`, "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, @@ -324,6 +366,13 @@ cc_test { ":libgtest_main", ]`, "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, @@ -350,6 +399,13 @@ cc_test { "deps": `[":libgtest_isolated_main"]`, "dynamic_deps": `[":liblog"]`, "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, @@ -381,6 +437,13 @@ cc_test { "gtest": "True", "target_compatible_with": `["//build/bazel/platforms/os:android"]`, "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, {"cc_test", "mytest_with_no_gtest", AttrNameToString{ @@ -388,6 +451,166 @@ cc_test { "gtest": "False", "target_compatible_with": `["//build/bazel/platforms/os:android"]`, "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, + }, + }, + }, + }) +} + +func TestCcTest_DisableMemtagHeap(t *testing.T) { + runCcTestTestCase(t, ccTestBp2buildTestCase{ + description: "cc test that disable memtag_heap", + blueprint: ` +cc_test { + name: "mytest", + srcs: ["test.cpp"], + isolated: true, + sanitize: { + cfi: true, + memtag_heap: false, + }, +} +` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + simpleModuleDoNotConvertBp2build("cc_library", "liblog"), + targets: []testBazelTarget{ + {"cc_test", "mytest", AttrNameToString{ + "local_includes": `["."]`, + "srcs": `["test.cpp"]`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + "deps": `[":libgtest_isolated_main"]`, + "dynamic_deps": `[":liblog"]`, + "runs_on": `["device"]`, + "features": `["android_cfi"] + select({ + "//build/bazel/platforms/os_arch:android_arm64": ["-memtag_heap"], + "//conditions:default": [], + })`, + }, + }, + }, + }) +} + +func TestCcTest_RespectArm64MemtagHeap(t *testing.T) { + runCcTestTestCase(t, ccTestBp2buildTestCase{ + description: "cc test that disable memtag_heap", + blueprint: ` +cc_test { + name: "mytest", + srcs: ["test.cpp"], + isolated: true, + target: { + android_arm64: { + sanitize: { + memtag_heap: false, + } + } + }, +} +` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + simpleModuleDoNotConvertBp2build("cc_library", "liblog"), + targets: []testBazelTarget{ + {"cc_test", "mytest", AttrNameToString{ + "local_includes": `["."]`, + "srcs": `["test.cpp"]`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + "deps": `[":libgtest_isolated_main"]`, + "dynamic_deps": `[":liblog"]`, + "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": ["-memtag_heap"], + "//conditions:default": [], + })`, + }, + }, + }, + }) +} + +func TestCcTest_IgnoreNoneArm64MemtagHeap(t *testing.T) { + runCcTestTestCase(t, ccTestBp2buildTestCase{ + description: "cc test that disable memtag_heap", + blueprint: ` +cc_test { + name: "mytest", + srcs: ["test.cpp"], + isolated: true, + arch: { + x86: { + sanitize: { + memtag_heap: false, + } + } + }, +} +` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + simpleModuleDoNotConvertBp2build("cc_library", "liblog"), + targets: []testBazelTarget{ + {"cc_test", "mytest", AttrNameToString{ + "local_includes": `["."]`, + "srcs": `["test.cpp"]`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + "deps": `[":libgtest_isolated_main"]`, + "dynamic_deps": `[":liblog"]`, + "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "memtag_heap", + "diag_memtag_heap", + ], + "//conditions:default": [], + })`, + }, + }, + }, + }) +} + +func TestCcTest_Arm64MemtagHeapOverrideNoConfigOne(t *testing.T) { + runCcTestTestCase(t, ccTestBp2buildTestCase{ + description: "cc test that disable memtag_heap", + blueprint: ` +cc_test { + name: "mytest", + srcs: ["test.cpp"], + isolated: true, + sanitize: { + memtag_heap: true, + }, + target: { + android_arm64: { + sanitize: { + memtag_heap: false, + diag: { + memtag_heap: false, + }, + } + } + }, +} +` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") + + simpleModuleDoNotConvertBp2build("cc_library", "liblog"), + targets: []testBazelTarget{ + {"cc_test", "mytest", AttrNameToString{ + "local_includes": `["."]`, + "srcs": `["test.cpp"]`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + "deps": `[":libgtest_isolated_main"]`, + "dynamic_deps": `[":liblog"]`, + "runs_on": `["device"]`, + "features": `select({ + "//build/bazel/platforms/os_arch:android_arm64": [ + "-memtag_heap", + "-diag_memtag_heap", + ], + "//conditions:default": [], + })`, }, }, }, diff --git a/cc/bp2build.go b/cc/bp2build.go index 7f78e283d..83553c8c2 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -851,7 +851,7 @@ func bp2BuildYasm(ctx android.Bp2buildMutatorContext, m *Module, ca compilerAttr return ret } -// bp2BuildParseBaseProps returns all compiler, linker, library attributes of a cc module.. +// bp2BuildParseBaseProps returns all compiler, linker, library attributes of a cc module. func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) baseAttributes { archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) archVariantLinkerProps := module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) @@ -1936,6 +1936,8 @@ func bp2buildSanitizerFeatures(ctx android.BazelConversionPathContext, m *Module sanitizerFeatures := bazel.StringListAttribute{} sanitizerCopts := bazel.StringListAttribute{} sanitizerCompilerInputs := bazel.LabelListAttribute{} + memtagFeatures := bazel.StringListAttribute{} + memtagFeature := "" bp2BuildPropParseHelper(ctx, m, &SanitizeProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) { var features []string if sanitizerProps, ok := props.(*SanitizeProperties); ok { @@ -1960,9 +1962,18 @@ func bp2buildSanitizerFeatures(ctx android.BazelConversionPathContext, m *Module features = append(features, "android_cfi_assembly_support") } } + + if sanitizerProps.Sanitize.Memtag_heap != nil { + if (axis == bazel.NoConfigAxis && memtagFeature == "") || + (axis == bazel.OsArchConfigurationAxis && config == bazel.OsArchAndroidArm64) { + memtagFeature = setMemtagValue(sanitizerProps, &memtagFeatures) + } + } sanitizerFeatures.SetSelectValue(axis, config, features) } }) + sanitizerFeatures.Append(memtagFeatures) + return sanitizerValues{ features: sanitizerFeatures, copts: sanitizerCopts, @@ -1970,6 +1981,26 @@ func bp2buildSanitizerFeatures(ctx android.BazelConversionPathContext, m *Module } } +func setMemtagValue(sanitizerProps *SanitizeProperties, memtagFeatures *bazel.StringListAttribute) string { + var features []string + if proptools.Bool(sanitizerProps.Sanitize.Memtag_heap) { + features = append(features, "memtag_heap") + } else { + features = append(features, "-memtag_heap") + } + // Logic comes from: https://cs.android.com/android/platform/superproject/main/+/32ea1afbd1148b0b78553f24fa61116c999eb968:build/soong/cc/sanitize.go;l=910 + if sanitizerProps.Sanitize.Diag.Memtag_heap != nil { + if proptools.Bool(sanitizerProps.Sanitize.Diag.Memtag_heap) { + features = append(features, "diag_memtag_heap") + } else { + features = append(features, "-diag_memtag_heap") + } + } + memtagFeatures.SetSelectValue(bazel.OsArchConfigurationAxis, bazel.OsArchAndroidArm64, features) + + return features[0] +} + func bp2buildLtoFeatures(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute { lto_feature_name := "android_thin_lto" ltoBoolFeatures := bazel.BoolAttribute{} diff --git a/cc/test.go b/cc/test.go index adc80c2f0..c643862ca 100644 --- a/cc/test.go +++ b/cc/test.go @@ -720,6 +720,21 @@ func testBinaryBp2build(ctx android.TopDownMutatorContext, m *Module) { } } + // The logic comes from https://cs.android.com/android/platform/superproject/main/+/0df8153267f96da877febc5332240fa06ceb8533:build/soong/cc/sanitize.go;l=488 + var features bazel.StringListAttribute + curFeatures := testBinaryAttrs.binaryAttributes.Features.SelectValue(bazel.OsArchConfigurationAxis, bazel.OsArchAndroidArm64) + var newFeatures []string + if !android.InList("memtag_heap", curFeatures) && !android.InList("-memtag_heap", curFeatures) { + newFeatures = append(newFeatures, "memtag_heap") + if !android.InList("diag_memtag_heap", curFeatures) && !android.InList("-diag_memtag_heap", curFeatures) { + newFeatures = append(newFeatures, "diag_memtag_heap") + } + } + + features.SetSelectValue(bazel.OsArchConfigurationAxis, bazel.OsArchAndroidArm64, newFeatures) + testBinaryAttrs.binaryAttributes.Features.Append(features) + testBinaryAttrs.binaryAttributes.Features.DeduplicateAxesFromBase() + m.convertTidyAttributes(ctx, &testBinaryAttrs.tidyAttributes) testBinary := m.linker.(*testBinary)