Loading Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ bootstrap_go_package { "cc/rs.go", "cc/sanitize.go", "cc/sabi.go", "cc/sdk.go", "cc/snapshot_utils.go", "cc/stl.go", "cc/strip.go", Loading android/neverallow.go +44 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ func init() { AddNeverAllowRules(createLibcoreRules()...) AddNeverAllowRules(createMediaRules()...) AddNeverAllowRules(createJavaDeviceForHostRules()...) AddNeverAllowRules(createCcSdkVariantRules()...) } // Add a NeverAllow rule to the set of rules to apply. Loading Loading @@ -175,6 +176,37 @@ func createJavaDeviceForHostRules() []Rule { } } func createCcSdkVariantRules() []Rule { sdkVersionOnlyWhitelist := []string{ // derive_sdk_prefer32 has stem: "derive_sdk" which conflicts with the derive_sdk. // This sometimes works because the APEX modules that contain derive_sdk and // derive_sdk_prefer32 suppress the platform installation rules, but fails when // the APEX modules contain the SDK variant and the platform variant still exists. "frameworks/base/apex/sdkextensions/derive_sdk", } platformVariantPropertiesWhitelist := []string{ // android_native_app_glue and libRSSupport use native_window.h but target old // sdk versions (minimum and 9 respectively) where libnativewindow didn't exist, // so they can't add libnativewindow to shared_libs to get the header directory // for the platform variant. Allow them to use the platform variant // property to set shared_libs. "prebuilts/ndk", "frameworks/rs", } return []Rule{ NeverAllow(). NotIn(sdkVersionOnlyWhitelist...). WithMatcher("sdk_variant_only", isSetMatcherInstance). Because("sdk_variant_only can only be used in whitelisted projects"), NeverAllow(). NotIn(platformVariantPropertiesWhitelist...). WithMatcher("platform.shared_libs", isSetMatcherInstance). Because("platform variant properties can only be used in whitelisted projects"), } } func neverallowMutator(ctx BottomUpMutatorContext) { m, ok := ctx.Module().(Module) if !ok { Loading Loading @@ -254,6 +286,18 @@ func (m *startsWithMatcher) String() string { return ".starts-with(" + m.prefix + ")" } type isSetMatcher struct{} func (m *isSetMatcher) test(value string) bool { return value != "" } func (m *isSetMatcher) String() string { return ".is-set" } var isSetMatcherInstance = &isSetMatcher{} type ruleProperty struct { fields []string // e.x.: Vndk.Enabled matcher ValueMatcher Loading android/neverallow_test.go +50 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,50 @@ var neverallowTests = []struct { }`), }, }, // CC sdk rule tests { name: `"sdk_variant_only" outside whitelist`, fs: map[string][]byte{ "Android.bp": []byte(` cc_library { name: "outside_whitelist", sdk_version: "current", sdk_variant_only: true, }`), }, expectedErrors: []string{ `module "outside_whitelist": violates neverallow`, }, }, { name: `"sdk_variant_only: false" outside whitelist`, fs: map[string][]byte{ "Android.bp": []byte(` cc_library { name: "outside_whitelist", sdk_version: "current", sdk_variant_only: false, }`), }, expectedErrors: []string{ `module "outside_whitelist": violates neverallow`, }, }, { name: `"platform" outside whitelist`, fs: map[string][]byte{ "Android.bp": []byte(` cc_library { name: "outside_whitelist", platform: { shared_libs: ["libfoo"], }, }`), }, expectedErrors: []string{ `module "outside_whitelist": violates neverallow`, }, }, } func TestNeverallow(t *testing.T) { Loading Loading @@ -289,6 +333,8 @@ type mockCcLibraryProperties struct { Include_dirs []string Vendor_available *bool Static_libs []string Sdk_version *string Sdk_variant_only *bool Vndk struct { Enabled *bool Loading @@ -305,6 +351,10 @@ type mockCcLibraryProperties struct { Cflags []string } } Platform struct { Shared_libs []string } } type mockCcLibraryModule struct { Loading apex/apex_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -3396,7 +3396,7 @@ func TestApexWithApps(t *testing.T) { } // JNI libraries including transitive deps are for _, jni := range []string{"libjni", "libfoo"} { jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module).OutputFile() jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_myapex").Module().(*cc.Module).OutputFile() // ... embedded inside APK (jnilibs.zip) ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String()) // ... and not directly inside the APEX Loading apex/vndk_test.go +2 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ func TestVndkApexUsesVendorVariant(t *testing.T) { system_shared_libs: [], stl: "none", notice: "custom_notice", sdk_version: "current", } cc_library { name: "libprofile-clang-extras_ndk", Loading @@ -98,6 +99,7 @@ func TestVndkApexUsesVendorVariant(t *testing.T) { system_shared_libs: [], stl: "none", notice: "custom_notice", sdk_version: "current", } `, func(fs map[string][]byte, config android.Config) { config.TestProductVariables.Native_coverage = proptools.BoolPtr(true) Loading Loading
Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -186,6 +186,7 @@ bootstrap_go_package { "cc/rs.go", "cc/sanitize.go", "cc/sabi.go", "cc/sdk.go", "cc/snapshot_utils.go", "cc/stl.go", "cc/strip.go", Loading
android/neverallow.go +44 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ func init() { AddNeverAllowRules(createLibcoreRules()...) AddNeverAllowRules(createMediaRules()...) AddNeverAllowRules(createJavaDeviceForHostRules()...) AddNeverAllowRules(createCcSdkVariantRules()...) } // Add a NeverAllow rule to the set of rules to apply. Loading Loading @@ -175,6 +176,37 @@ func createJavaDeviceForHostRules() []Rule { } } func createCcSdkVariantRules() []Rule { sdkVersionOnlyWhitelist := []string{ // derive_sdk_prefer32 has stem: "derive_sdk" which conflicts with the derive_sdk. // This sometimes works because the APEX modules that contain derive_sdk and // derive_sdk_prefer32 suppress the platform installation rules, but fails when // the APEX modules contain the SDK variant and the platform variant still exists. "frameworks/base/apex/sdkextensions/derive_sdk", } platformVariantPropertiesWhitelist := []string{ // android_native_app_glue and libRSSupport use native_window.h but target old // sdk versions (minimum and 9 respectively) where libnativewindow didn't exist, // so they can't add libnativewindow to shared_libs to get the header directory // for the platform variant. Allow them to use the platform variant // property to set shared_libs. "prebuilts/ndk", "frameworks/rs", } return []Rule{ NeverAllow(). NotIn(sdkVersionOnlyWhitelist...). WithMatcher("sdk_variant_only", isSetMatcherInstance). Because("sdk_variant_only can only be used in whitelisted projects"), NeverAllow(). NotIn(platformVariantPropertiesWhitelist...). WithMatcher("platform.shared_libs", isSetMatcherInstance). Because("platform variant properties can only be used in whitelisted projects"), } } func neverallowMutator(ctx BottomUpMutatorContext) { m, ok := ctx.Module().(Module) if !ok { Loading Loading @@ -254,6 +286,18 @@ func (m *startsWithMatcher) String() string { return ".starts-with(" + m.prefix + ")" } type isSetMatcher struct{} func (m *isSetMatcher) test(value string) bool { return value != "" } func (m *isSetMatcher) String() string { return ".is-set" } var isSetMatcherInstance = &isSetMatcher{} type ruleProperty struct { fields []string // e.x.: Vndk.Enabled matcher ValueMatcher Loading
android/neverallow_test.go +50 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,50 @@ var neverallowTests = []struct { }`), }, }, // CC sdk rule tests { name: `"sdk_variant_only" outside whitelist`, fs: map[string][]byte{ "Android.bp": []byte(` cc_library { name: "outside_whitelist", sdk_version: "current", sdk_variant_only: true, }`), }, expectedErrors: []string{ `module "outside_whitelist": violates neverallow`, }, }, { name: `"sdk_variant_only: false" outside whitelist`, fs: map[string][]byte{ "Android.bp": []byte(` cc_library { name: "outside_whitelist", sdk_version: "current", sdk_variant_only: false, }`), }, expectedErrors: []string{ `module "outside_whitelist": violates neverallow`, }, }, { name: `"platform" outside whitelist`, fs: map[string][]byte{ "Android.bp": []byte(` cc_library { name: "outside_whitelist", platform: { shared_libs: ["libfoo"], }, }`), }, expectedErrors: []string{ `module "outside_whitelist": violates neverallow`, }, }, } func TestNeverallow(t *testing.T) { Loading Loading @@ -289,6 +333,8 @@ type mockCcLibraryProperties struct { Include_dirs []string Vendor_available *bool Static_libs []string Sdk_version *string Sdk_variant_only *bool Vndk struct { Enabled *bool Loading @@ -305,6 +351,10 @@ type mockCcLibraryProperties struct { Cflags []string } } Platform struct { Shared_libs []string } } type mockCcLibraryModule struct { Loading
apex/apex_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -3396,7 +3396,7 @@ func TestApexWithApps(t *testing.T) { } // JNI libraries including transitive deps are for _, jni := range []string{"libjni", "libfoo"} { jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module).OutputFile() jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_myapex").Module().(*cc.Module).OutputFile() // ... embedded inside APK (jnilibs.zip) ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String()) // ... and not directly inside the APEX Loading
apex/vndk_test.go +2 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ func TestVndkApexUsesVendorVariant(t *testing.T) { system_shared_libs: [], stl: "none", notice: "custom_notice", sdk_version: "current", } cc_library { name: "libprofile-clang-extras_ndk", Loading @@ -98,6 +99,7 @@ func TestVndkApexUsesVendorVariant(t *testing.T) { system_shared_libs: [], stl: "none", notice: "custom_notice", sdk_version: "current", } `, func(fs map[string][]byte, config android.Config) { config.TestProductVariables.Native_coverage = proptools.BoolPtr(true) Loading