Allow neverallow rules to be defined by custom bootstrap_go_packages
* Adds a Rule interface to hide the rule struct and expose the mutator
functions.
* Makes the neverallow() function public as NeverAllow().
* Adds AddNeverAllowRules func to add more rules.
* Moves the population of the builtin rules to init() function.
Bug: 136159343
Test: m droid
- changed a built in rule to cause build failure to ensure the
rules were still being applied, then reverted the change and
ran 'm droid' again.
Change-Id: Ie3a4456d1f6bc12c5b4931bf698333275347fdf0
Merged-In: Ie3a4456d1f6bc12c5b4931bf698333275347fdf0
diff --git a/android/neverallow.go b/android/neverallow.go
index f35d1fe..1893e8b 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -31,61 +31,64 @@
// work regardless of these restrictions.
//
// A module is disallowed if all of the following are true:
-// - it is in one of the "in" paths
-// - it is not in one of the "notIn" paths
-// - it has all "with" properties matched
+// - it is in one of the "In" paths
+// - it is not in one of the "NotIn" paths
+// - it has all "With" properties matched
// - - values are matched in their entirety
// - - nil is interpreted as an empty string
// - - nested properties are separated with a '.'
// - - if the property is a list, any of the values in the list being matches
// counts as a match
-// - it has none of the "without" properties matched (same rules as above)
+// - it has none of the "Without" properties matched (same rules as above)
func registerNeverallowMutator(ctx RegisterMutatorsContext) {
ctx.BottomUp("neverallow", neverallowMutator).Parallel()
}
-var neverallows = createNeverAllows()
+var neverallows = []Rule{}
-func createNeverAllows() []*rule {
- rules := []*rule{}
- rules = append(rules, createTrebleRules()...)
- rules = append(rules, createLibcoreRules()...)
- rules = append(rules, createJavaDeviceForHostRules()...)
- return rules
+func init() {
+ AddNeverAllowRules(createTrebleRules()...)
+ AddNeverAllowRules(createLibcoreRules()...)
+ AddNeverAllowRules(createJavaDeviceForHostRules()...)
}
-func createTrebleRules() []*rule {
- return []*rule{
- neverallow().
- in("vendor", "device").
- with("vndk.enabled", "true").
- without("vendor", "true").
- because("the VNDK can never contain a library that is device dependent."),
- neverallow().
- with("vndk.enabled", "true").
- without("vendor", "true").
- without("owner", "").
- because("a VNDK module can never have an owner."),
+// Add a NeverAllow rule to the set of rules to apply.
+func AddNeverAllowRules(rules ...Rule) {
+ neverallows = append(neverallows, rules...)
+}
+
+func createTrebleRules() []Rule {
+ return []Rule{
+ NeverAllow().
+ In("vendor", "device").
+ With("vndk.enabled", "true").
+ Without("vendor", "true").
+ Because("the VNDK can never contain a library that is device dependent."),
+ NeverAllow().
+ With("vndk.enabled", "true").
+ Without("vendor", "true").
+ Without("owner", "").
+ Because("a VNDK module can never have an owner."),
// TODO(b/67974785): always enforce the manifest
- neverallow().
- without("name", "libhidltransport").
- with("product_variables.enforce_vintf_manifest.cflags", "*").
- because("manifest enforcement should be independent of ."),
+ NeverAllow().
+ Without("name", "libhidltransport").
+ With("product_variables.enforce_vintf_manifest.cflags", "*").
+ Because("manifest enforcement should be independent of ."),
// TODO(b/67975799): vendor code should always use /vendor/bin/sh
- neverallow().
- without("name", "libc_bionic_ndk").
- with("product_variables.treble_linker_namespaces.cflags", "*").
- because("nothing should care if linker namespaces are enabled or not"),
+ NeverAllow().
+ Without("name", "libc_bionic_ndk").
+ With("product_variables.treble_linker_namespaces.cflags", "*").
+ Because("nothing should care if linker namespaces are enabled or not"),
// Example:
- // *neverallow().with("Srcs", "main.cpp"))
+ // *NeverAllow().with("Srcs", "main.cpp"))
}
}
-func createLibcoreRules() []*rule {
+func createLibcoreRules() []Rule {
var coreLibraryProjects = []string{
"libcore",
"external/apache-harmony",
@@ -102,27 +105,27 @@
// Core library constraints. The sdk_version: "none" can only be used in core library projects.
// Access to core library targets is restricted using visibility rules.
- rules := []*rule{
- neverallow().
- notIn(coreLibraryProjects...).
- with("sdk_version", "none"),
+ rules := []Rule{
+ NeverAllow().
+ NotIn(coreLibraryProjects...).
+ With("sdk_version", "none"),
}
return rules
}
-func createJavaDeviceForHostRules() []*rule {
+func createJavaDeviceForHostRules() []Rule {
javaDeviceForHostProjectsWhitelist := []string{
"external/guava",
"external/robolectric-shadows",
"framework/layoutlib",
}
- return []*rule{
- neverallow().
- notIn(javaDeviceForHostProjectsWhitelist...).
- moduleType("java_device_for_host", "java_host_for_device").
- because("java_device_for_host can only be used in whitelisted projects"),
+ return []Rule{
+ NeverAllow().
+ NotIn(javaDeviceForHostProjectsWhitelist...).
+ ModuleType("java_device_for_host", "java_host_for_device").
+ Because("java_device_for_host can only be used in whitelisted projects"),
}
}
@@ -135,7 +138,8 @@
dir := ctx.ModuleDir() + "/"
properties := m.GetProperties()
- for _, n := range neverallows {
+ for _, r := range neverallows {
+ n := r.(*rule)
if !n.appliesToPath(dir) {
continue
}
@@ -157,6 +161,23 @@
value string // e.x.: true
}
+// A NeverAllow rule.
+type Rule interface {
+ In(path ...string) Rule
+
+ NotIn(path ...string) Rule
+
+ ModuleType(types ...string) Rule
+
+ NotModuleType(types ...string) Rule
+
+ With(properties, value string) Rule
+
+ Without(properties, value string) Rule
+
+ Because(reason string) Rule
+}
+
type rule struct {
// User string for why this is a thing.
reason string
@@ -171,31 +192,32 @@
unlessProps []ruleProperty
}
-func neverallow() *rule {
+// Create a new NeverAllow rule.
+func NeverAllow() Rule {
return &rule{}
}
-func (r *rule) in(path ...string) *rule {
+func (r *rule) In(path ...string) Rule {
r.paths = append(r.paths, cleanPaths(path)...)
return r
}
-func (r *rule) notIn(path ...string) *rule {
+func (r *rule) NotIn(path ...string) Rule {
r.unlessPaths = append(r.unlessPaths, cleanPaths(path)...)
return r
}
-func (r *rule) moduleType(types ...string) *rule {
+func (r *rule) ModuleType(types ...string) Rule {
r.moduleTypes = append(r.moduleTypes, types...)
return r
}
-func (r *rule) notModuleType(types ...string) *rule {
+func (r *rule) NotModuleType(types ...string) Rule {
r.unlessModuleTypes = append(r.unlessModuleTypes, types...)
return r
}
-func (r *rule) with(properties, value string) *rule {
+func (r *rule) With(properties, value string) Rule {
r.props = append(r.props, ruleProperty{
fields: fieldNamesForProperties(properties),
value: value,
@@ -203,7 +225,7 @@
return r
}
-func (r *rule) without(properties, value string) *rule {
+func (r *rule) Without(properties, value string) Rule {
r.unlessProps = append(r.unlessProps, ruleProperty{
fields: fieldNamesForProperties(properties),
value: value,
@@ -211,7 +233,7 @@
return r
}
-func (r *rule) because(reason string) *rule {
+func (r *rule) Because(reason string) Rule {
r.reason = reason
return r
}