From db7e0263f48a3fecad02e554c34d030807156bc0 Mon Sep 17 00:00:00 2001 From: Trevor Radcliffe Date: Fri, 28 Oct 2022 16:48:18 +0000 Subject: [PATCH] bp2build conversion for Sanitize.Integer_overflow and Sanitize.Misc_undefined. This is a redo of aosp/2277186 with changes to account for issues in mixed builds. Specifically, for now we're disabling mixed builds for modules that use ubsan. This bug tracks enabling it: b/261058727. Bug: 253428057 Test: Unit tests Change-Id: Ia1277a7fa9a82f40998d7f3d2c40ea90f38201e7 --- bp2build/cc_binary_conversion_test.go | 79 +++++++++++++ bp2build/cc_library_conversion_test.go | 110 ++++++++++++++++++ bp2build/cc_library_shared_conversion_test.go | 82 +++++++++++++ bp2build/cc_library_static_conversion_test.go | 82 +++++++++++++ cc/bp2build.go | 21 +++- cc/cc.go | 7 +- 6 files changed, 377 insertions(+), 4 deletions(-) diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 8aa2c3ecb..fe156dffd 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -789,3 +789,82 @@ func TestCcBinaryWithSyspropSrcsSomeConfigs(t *testing.T) { }, }) } + +func TestCcBinaryWithIntegerOverflowProperty(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary with integer overflow property specified", + blueprint: ` +{rule_name} { + name: "foo", + sanitize: { + integer_overflow: true, + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "local_includes": `["."]`, + "features": `["ubsan_integer_overflow"]`, + }}, + }, + }) +} + +func TestCcBinaryWithMiscUndefinedProperty(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary with miscellaneous properties specified", + blueprint: ` +{rule_name} { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "local_includes": `["."]`, + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + }}, + }, + }) +} + +func TestCcBinaryWithUBSanPropertiesArchSpecific(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary has correct feature select when UBSan props are specified in arch specific blocks", + blueprint: ` +{rule_name} { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, + target: { + android: { + sanitize: { + misc_undefined: ["alignment"], + }, + }, + linux_glibc: { + sanitize: { + integer_overflow: true, + }, + }, + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "local_includes": `["."]`, + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + }}, + }, + }) +} diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 595ee637a..f924d00f4 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -3908,3 +3908,113 @@ cc_library { }, ) } + +func TestCcLibraryWithIntegerOverflowProperty(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library has correct features when integer_overflow property is provided", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + sanitize: { + integer_overflow: true, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `["ubsan_integer_overflow"]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `["ubsan_integer_overflow"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryWithMiscUndefinedProperty(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library has correct features when misc_undefined property is provided", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryWithUBSanPropertiesArchSpecific(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library has correct feature select when UBSan props are specified in arch specific blocks", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, + target: { + android: { + sanitize: { + misc_undefined: ["alignment"], + }, + }, + linux_glibc: { + sanitize: { + integer_overflow: true, + }, + }, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 14b6f0d2f..017df6f9c 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -885,3 +885,85 @@ func TestCcLibrarySharedHeaderAbiChecker(t *testing.T) { }, }) } + +func TestCcLibrarySharedWithIntegerOverflowProperty(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct features when integer_overflow property is provided", + Blueprint: ` +cc_library_shared { + name: "foo", + sanitize: { + integer_overflow: true, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `["ubsan_integer_overflow"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibrarySharedWithMiscUndefinedProperty(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct features when misc_undefined property is provided", + Blueprint: ` +cc_library_shared { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibrarySharedWithUBSanPropertiesArchSpecific(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct feature select when UBSan props are specified in arch specific blocks", + Blueprint: ` +cc_library_shared { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, + target: { + android: { + sanitize: { + misc_undefined: ["alignment"], + }, + }, + linux_glibc: { + sanitize: { + integer_overflow: true, + }, + }, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index b47d1f1f1..5a1260f94 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -1723,3 +1723,85 @@ cc_library_static { }, }) } + +func TestCcLibraryStaticWithIntegerOverflowProperty(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct features when integer_overflow property is provided", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + integer_overflow: true, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `["ubsan_integer_overflow"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryStaticWithMiscUndefinedProperty(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct features when misc_undefined property is provided", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryStaticWithUBSanPropertiesArchSpecific(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct feature select when UBSan props are specified in arch specific blocks", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + misc_undefined: ["undefined", "nullability"], + }, + target: { + android: { + sanitize: { + misc_undefined: ["alignment"], + }, + }, + linux_glibc: { + sanitize: { + integer_overflow: true, + }, + }, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `[ + "ubsan_undefined", + "ubsan_nullability", + ] + select({ + "//build/bazel/platforms/os:android": ["ubsan_alignment"], + "//build/bazel/platforms/os:linux_glibc": ["ubsan_integer_overflow"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/cc/bp2build.go b/cc/bp2build.go index 66157aec4..a7ee5d129 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -354,7 +354,7 @@ type baseAttributes struct { compilerAttributes linkerAttributes - // A combination of compilerAttributes.features and linkerAttributes.features + // A combination of compilerAttributes.features and linkerAttributes.features, as well as sanitizer features features bazel.StringListAttribute protoDependency *bazel.LabelAttribute aidlDependency *bazel.LabelAttribute @@ -804,7 +804,7 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) (&linkerAttrs).wholeArchiveDeps.Add(bp2buildCcSysprop(ctx, module.Name(), module.Properties.Min_sdk_version, compilerAttrs.syspropSrcs)) } - features := compilerAttrs.features.Clone().Append(linkerAttrs.features) + features := compilerAttrs.features.Clone().Append(linkerAttrs.features).Append(bp2buildSanitizerFeatures(ctx, module)) features.DeduplicateAxesFromBase() return baseAttributes{ @@ -1430,3 +1430,20 @@ func bp2buildBinaryLinkerProps(ctx android.BazelConversionPathContext, m *Module return attrs } + +func bp2buildSanitizerFeatures(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute { + sanitizerFeatures := bazel.StringListAttribute{} + bp2BuildPropParseHelper(ctx, m, &SanitizeProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) { + var features []string + if sanitizerProps, ok := props.(*SanitizeProperties); ok { + if sanitizerProps.Sanitize.Integer_overflow != nil && *sanitizerProps.Sanitize.Integer_overflow { + features = append(features, "ubsan_integer_overflow") + } + for _, sanitizer := range sanitizerProps.Sanitize.Misc_undefined { + features = append(features, "ubsan_"+sanitizer) + } + sanitizerFeatures.SetSelectValue(axis, config, features) + } + }) + return sanitizerFeatures +} diff --git a/cc/cc.go b/cc/cc.go index 6ca25758b..1611b7d86 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1873,8 +1873,11 @@ func (c *Module) IsMixedBuildSupported(ctx android.BaseModuleContext) bool { return false } - // Enable mixed builds as long as the cc_* module type has a bazel handler. - return c.bazelHandler != nil + // TODO(b/261058727): Remove this (enable mixed builds for modules with UBSan) + ubsanEnabled := c.sanitize != nil && + ((c.sanitize.Properties.Sanitize.Integer_overflow != nil && *c.sanitize.Properties.Sanitize.Integer_overflow) || + c.sanitize.Properties.Sanitize.Misc_undefined != nil) + return c.bazelHandler != nil && !ubsanEnabled } func (c *Module) ProcessBazelQueryResponse(ctx android.ModuleContext) {