summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/neverallow.go40
-rw-r--r--apex/apex.go67
-rw-r--r--apex/apex_test.go135
3 files changed, 242 insertions, 0 deletions
diff --git a/android/neverallow.go b/android/neverallow.go
index fc6687e60..928f3fc4e 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -258,6 +258,10 @@ func neverallowMutator(ctx BottomUpMutatorContext) {
continue
}
+ if !n.appliesToBootclasspathJar(ctx) {
+ continue
+ }
+
ctx.ModuleErrorf("violates " + n.String())
}
}
@@ -316,6 +320,18 @@ func (m *regexMatcher) String() string {
return ".regexp(" + m.re.String() + ")"
}
+type notInListMatcher struct {
+ allowed []string
+}
+
+func (m *notInListMatcher) Test(value string) bool {
+ return !InList(value, m.allowed)
+}
+
+func (m *notInListMatcher) String() string {
+ return ".not-in-list(" + strings.Join(m.allowed, ",") + ")"
+}
+
type isSetMatcher struct{}
func (m *isSetMatcher) Test(value string) bool {
@@ -347,6 +363,8 @@ type Rule interface {
NotModuleType(types ...string) Rule
+ BootclasspathJar() Rule
+
With(properties, value string) Rule
WithMatcher(properties string, matcher ValueMatcher) Rule
@@ -374,6 +392,8 @@ type rule struct {
props []ruleProperty
unlessProps []ruleProperty
+
+ onlyBootclasspathJar bool
}
// Create a new NeverAllow rule.
@@ -449,6 +469,11 @@ func (r *rule) Because(reason string) Rule {
return r
}
+func (r *rule) BootclasspathJar() Rule {
+ r.onlyBootclasspathJar = true
+ return r
+}
+
func (r *rule) String() string {
s := "neverallow"
for _, v := range r.paths {
@@ -475,6 +500,9 @@ func (r *rule) String() string {
for _, v := range r.osClasses {
s += " os:" + v.String()
}
+ if r.onlyBootclasspathJar {
+ s += " inBcp"
+ }
if len(r.reason) != 0 {
s += " which is restricted because " + r.reason
}
@@ -503,6 +531,14 @@ func (r *rule) appliesToDirectDeps(ctx BottomUpMutatorContext) bool {
return matches
}
+func (r *rule) appliesToBootclasspathJar(ctx BottomUpMutatorContext) bool {
+ if !r.onlyBootclasspathJar {
+ return true
+ }
+
+ return InList(ctx.ModuleName(), ctx.Config().BootJars())
+}
+
func (r *rule) appliesToOsClass(osClass OsClass) bool {
if len(r.osClasses) == 0 {
return true
@@ -539,6 +575,10 @@ func Regexp(re string) ValueMatcher {
return &regexMatcher{r}
}
+func NotInList(allowed []string) ValueMatcher {
+ return &notInListMatcher{allowed}
+}
+
// assorted utils
func cleanPaths(paths []string) []string {
diff --git a/apex/apex.go b/apex/apex.go
index 36c53e61d..037b136f0 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -681,6 +681,55 @@ func makeApexAvailableBaseline() map[string][]string {
return m
}
+// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
+// Adding code to the bootclasspath in new packages will cause issues on module update.
+func qModulesPackages() map[string][]string {
+ return map[string][]string{
+ "com.android.conscrypt": []string{
+ "android.net.ssl",
+ "com.android.org.conscrypt",
+ },
+ "com.android.media": []string{
+ "android.media",
+ },
+ }
+}
+
+// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
+// Adding code to the bootclasspath in new packages will cause issues on module update.
+func rModulesPackages() map[string][]string {
+ return map[string][]string{
+ "com.android.mediaprovider": []string{
+ "android.provider",
+ },
+ "com.android.permission": []string{
+ "android.permission",
+ "android.app.role",
+ "com.android.permission",
+ "com.android.role",
+ },
+ "com.android.sdkext": []string{
+ "android.os.ext",
+ },
+ "com.android.os.statsd": []string{
+ "android.app",
+ "android.os",
+ "android.util",
+ "com.android.internal.statsd",
+ "com.android.server.stats",
+ },
+ "com.android.wifi": []string{
+ "com.android.server.wifi",
+ "com.android.wifi.x",
+ "android.hardware.wifi",
+ "android.net.wifi",
+ },
+ "com.android.tethering": []string{
+ "android.net",
+ },
+ }
+}
+
func init() {
android.RegisterModuleType("apex", BundleFactory)
android.RegisterModuleType("apex_test", testApexBundleFactory)
@@ -698,6 +747,24 @@ func init() {
sort.Strings(*apexFileContextsInfos)
ctx.Strict("APEX_FILE_CONTEXTS_INFOS", strings.Join(*apexFileContextsInfos, " "))
})
+
+ android.AddNeverAllowRules(createApexPermittedPackagesRules(qModulesPackages())...)
+ android.AddNeverAllowRules(createApexPermittedPackagesRules(rModulesPackages())...)
+}
+
+func createApexPermittedPackagesRules(modules_packages map[string][]string) []android.Rule {
+ rules := make([]android.Rule, 0, len(modules_packages))
+ for module_name, module_packages := range modules_packages {
+ permitted_packages_rule := android.NeverAllow().
+ BootclasspathJar().
+ With("apex_available", module_name).
+ WithMatcher("permitted_packages", android.NotInList(module_packages)).
+ Because("jars that are part of the " + module_name +
+ " module may only allow these packages: " + strings.Join(module_packages, ",") +
+ ". Please jarjar or move code around.")
+ rules = append(rules, permitted_packages_rule)
+ }
+ return rules
}
func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 24f0e4f6d..e7e53c0bd 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5226,6 +5226,141 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
})
}
+func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJars []string, rules []android.Rule) {
+ t.Helper()
+ android.ClearApexDependency()
+ bp += `
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }`
+ fs := map[string][]byte{
+ "lib1/src/A.java": nil,
+ "lib2/src/B.java": nil,
+ "system/sepolicy/apex/myapex-file_contexts": nil,
+ }
+
+ ctx := android.NewTestArchContext()
+ ctx.RegisterModuleType("apex", BundleFactory)
+ ctx.RegisterModuleType("apex_key", ApexKeyFactory)
+ ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ cc.RegisterRequiredBuildComponentsForTest(ctx)
+ java.RegisterJavaBuildComponents(ctx)
+ java.RegisterSystemModulesBuildComponents(ctx)
+ java.RegisterDexpreoptBootJarsComponents(ctx)
+ ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
+ ctx.PreDepsMutators(RegisterPreDepsMutators)
+ ctx.PostDepsMutators(RegisterPostDepsMutators)
+ ctx.PostDepsMutators(android.RegisterNeverallowMutator)
+
+ config := android.TestArchConfig(buildDir, nil, bp, fs)
+ android.SetTestNeverallowRules(config, rules)
+ updatableBootJars := make([]string, 0, len(apexBootJars))
+ for _, apexBootJar := range apexBootJars {
+ updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
+ }
+ config.TestProductVariables.UpdatableBootJars = updatableBootJars
+
+ ctx.Register(config)
+
+ _, errs := ctx.ParseBlueprintsFiles("Android.bp")
+ android.FailIfErrored(t, errs)
+
+ _, errs = ctx.PrepareBuildActions(config)
+ if errmsg == "" {
+ android.FailIfErrored(t, errs)
+ } else if len(errs) > 0 {
+ android.FailIfNoMatchingErrors(t, errmsg, errs)
+ return
+ } else {
+ t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
+ }
+}
+
+func TestApexPermittedPackagesRules(t *testing.T) {
+ testcases := []struct {
+ name string
+ expectedError string
+ bp string
+ bootJars []string
+ modulesPackages map[string][]string
+ }{
+
+ {
+ name: "Non-Bootclasspath apex jar not satisfying allowed module packages.",
+ expectedError: "",
+ bp: `
+ java_library {
+ name: "bcp_lib1",
+ srcs: ["lib1/src/*.java"],
+ permitted_packages: ["foo.bar"],
+ apex_available: ["myapex"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ java_library {
+ name: "nonbcp_lib2",
+ srcs: ["lib2/src/*.java"],
+ apex_available: ["myapex"],
+ permitted_packages: ["a.b"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["bcp_lib1", "nonbcp_lib2"],
+ }`,
+ bootJars: []string{"bcp_lib1"},
+ modulesPackages: map[string][]string{
+ "myapex": []string{
+ "foo.bar",
+ },
+ },
+ },
+ {
+ name: "Bootclasspath apex jar not satisfying allowed module packages.",
+ expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar. Please jarjar or move code around.`,
+ bp: `
+ java_library {
+ name: "bcp_lib1",
+ srcs: ["lib1/src/*.java"],
+ apex_available: ["myapex"],
+ permitted_packages: ["foo.bar"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ java_library {
+ name: "bcp_lib2",
+ srcs: ["lib2/src/*.java"],
+ apex_available: ["myapex"],
+ permitted_packages: ["foo.bar", "bar.baz"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["bcp_lib1", "bcp_lib2"],
+ }
+ `,
+ bootJars: []string{"bcp_lib1", "bcp_lib2"},
+ modulesPackages: map[string][]string{
+ "myapex": []string{
+ "foo.bar",
+ },
+ },
+ },
+ }
+ for _, tc := range testcases {
+ t.Run(tc.name, func(t *testing.T) {
+ rules := createApexPermittedPackagesRules(tc.modulesPackages)
+ testApexPermittedPackagesRules(t, tc.expectedError, tc.bp, tc.bootJars, rules)
+ })
+ }
+}
+
func TestTestFor(t *testing.T) {
ctx, _ := testApex(t, `
apex {