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
This commit is contained in:
@@ -31,62 +31,65 @@ import (
|
|||||||
// work regardless of these restrictions.
|
// work regardless of these restrictions.
|
||||||
//
|
//
|
||||||
// A module is disallowed if all of the following are true:
|
// A module is disallowed if all of the following are true:
|
||||||
// - it is in one of the "in" paths
|
// - it is in one of the "In" paths
|
||||||
// - it is not in one of the "notIn" paths
|
// - it is not in one of the "NotIn" paths
|
||||||
// - it has all "with" properties matched
|
// - it has all "With" properties matched
|
||||||
// - - values are matched in their entirety
|
// - - values are matched in their entirety
|
||||||
// - - nil is interpreted as an empty string
|
// - - nil is interpreted as an empty string
|
||||||
// - - nested properties are separated with a '.'
|
// - - nested properties are separated with a '.'
|
||||||
// - - if the property is a list, any of the values in the list being matches
|
// - - if the property is a list, any of the values in the list being matches
|
||||||
// counts as a match
|
// 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) {
|
func registerNeverallowMutator(ctx RegisterMutatorsContext) {
|
||||||
ctx.BottomUp("neverallow", neverallowMutator).Parallel()
|
ctx.BottomUp("neverallow", neverallowMutator).Parallel()
|
||||||
}
|
}
|
||||||
|
|
||||||
var neverallows = createNeverAllows()
|
var neverallows = []Rule{}
|
||||||
|
|
||||||
func createNeverAllows() []*rule {
|
func init() {
|
||||||
rules := []*rule{}
|
AddNeverAllowRules(createTrebleRules()...)
|
||||||
rules = append(rules, createTrebleRules()...)
|
AddNeverAllowRules(createLibcoreRules()...)
|
||||||
rules = append(rules, createLibcoreRules()...)
|
AddNeverAllowRules(createMediaRules()...)
|
||||||
rules = append(rules, createMediaRules()...)
|
AddNeverAllowRules(createJavaDeviceForHostRules()...)
|
||||||
rules = append(rules, createJavaDeviceForHostRules()...)
|
|
||||||
return rules
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTrebleRules() []*rule {
|
// Add a NeverAllow rule to the set of rules to apply.
|
||||||
return []*rule{
|
func AddNeverAllowRules(rules ...Rule) {
|
||||||
neverallow().
|
neverallows = append(neverallows, rules...)
|
||||||
in("vendor", "device").
|
}
|
||||||
with("vndk.enabled", "true").
|
|
||||||
without("vendor", "true").
|
func createTrebleRules() []Rule {
|
||||||
because("the VNDK can never contain a library that is device dependent."),
|
return []Rule{
|
||||||
neverallow().
|
NeverAllow().
|
||||||
with("vndk.enabled", "true").
|
In("vendor", "device").
|
||||||
without("vendor", "true").
|
With("vndk.enabled", "true").
|
||||||
without("owner", "").
|
Without("vendor", "true").
|
||||||
because("a VNDK module can never have an owner."),
|
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
|
// TODO(b/67974785): always enforce the manifest
|
||||||
neverallow().
|
NeverAllow().
|
||||||
without("name", "libhidltransport-impl-internal").
|
Without("name", "libhidltransport-impl-internal").
|
||||||
with("product_variables.enforce_vintf_manifest.cflags", "*").
|
With("product_variables.enforce_vintf_manifest.cflags", "*").
|
||||||
because("manifest enforcement should be independent of ."),
|
Because("manifest enforcement should be independent of ."),
|
||||||
|
|
||||||
// TODO(b/67975799): vendor code should always use /vendor/bin/sh
|
// TODO(b/67975799): vendor code should always use /vendor/bin/sh
|
||||||
neverallow().
|
NeverAllow().
|
||||||
without("name", "libc_bionic_ndk").
|
Without("name", "libc_bionic_ndk").
|
||||||
with("product_variables.treble_linker_namespaces.cflags", "*").
|
With("product_variables.treble_linker_namespaces.cflags", "*").
|
||||||
because("nothing should care if linker namespaces are enabled or not"),
|
Because("nothing should care if linker namespaces are enabled or not"),
|
||||||
|
|
||||||
// Example:
|
// Example:
|
||||||
// *neverallow().with("Srcs", "main.cpp"))
|
// *NeverAllow().with("Srcs", "main.cpp"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createLibcoreRules() []*rule {
|
func createLibcoreRules() []Rule {
|
||||||
var coreLibraryProjects = []string{
|
var coreLibraryProjects = []string{
|
||||||
"libcore",
|
"libcore",
|
||||||
"external/apache-harmony",
|
"external/apache-harmony",
|
||||||
@@ -103,35 +106,35 @@ func createLibcoreRules() []*rule {
|
|||||||
|
|
||||||
// Core library constraints. The sdk_version: "none" can only be used in core library projects.
|
// 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.
|
// Access to core library targets is restricted using visibility rules.
|
||||||
rules := []*rule{
|
rules := []Rule{
|
||||||
neverallow().
|
NeverAllow().
|
||||||
notIn(coreLibraryProjects...).
|
NotIn(coreLibraryProjects...).
|
||||||
with("sdk_version", "none"),
|
With("sdk_version", "none"),
|
||||||
}
|
}
|
||||||
|
|
||||||
return rules
|
return rules
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMediaRules() []*rule {
|
func createMediaRules() []Rule {
|
||||||
return []*rule{
|
return []Rule{
|
||||||
neverallow().
|
NeverAllow().
|
||||||
with("libs", "updatable-media").
|
With("libs", "updatable-media").
|
||||||
because("updatable-media includes private APIs. Use updatable_media_stubs instead."),
|
Because("updatable-media includes private APIs. Use updatable_media_stubs instead."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createJavaDeviceForHostRules() []*rule {
|
func createJavaDeviceForHostRules() []Rule {
|
||||||
javaDeviceForHostProjectsWhitelist := []string{
|
javaDeviceForHostProjectsWhitelist := []string{
|
||||||
"external/guava",
|
"external/guava",
|
||||||
"external/robolectric-shadows",
|
"external/robolectric-shadows",
|
||||||
"framework/layoutlib",
|
"framework/layoutlib",
|
||||||
}
|
}
|
||||||
|
|
||||||
return []*rule{
|
return []Rule{
|
||||||
neverallow().
|
NeverAllow().
|
||||||
notIn(javaDeviceForHostProjectsWhitelist...).
|
NotIn(javaDeviceForHostProjectsWhitelist...).
|
||||||
moduleType("java_device_for_host", "java_host_for_device").
|
ModuleType("java_device_for_host", "java_host_for_device").
|
||||||
because("java_device_for_host can only be used in whitelisted projects"),
|
Because("java_device_for_host can only be used in whitelisted projects"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +147,8 @@ func neverallowMutator(ctx BottomUpMutatorContext) {
|
|||||||
dir := ctx.ModuleDir() + "/"
|
dir := ctx.ModuleDir() + "/"
|
||||||
properties := m.GetProperties()
|
properties := m.GetProperties()
|
||||||
|
|
||||||
for _, n := range neverallows {
|
for _, r := range neverallows {
|
||||||
|
n := r.(*rule)
|
||||||
if !n.appliesToPath(dir) {
|
if !n.appliesToPath(dir) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -166,6 +170,23 @@ type ruleProperty struct {
|
|||||||
value string // e.x.: true
|
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 {
|
type rule struct {
|
||||||
// User string for why this is a thing.
|
// User string for why this is a thing.
|
||||||
reason string
|
reason string
|
||||||
@@ -180,31 +201,32 @@ type rule struct {
|
|||||||
unlessProps []ruleProperty
|
unlessProps []ruleProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
func neverallow() *rule {
|
// Create a new NeverAllow rule.
|
||||||
|
func NeverAllow() Rule {
|
||||||
return &rule{}
|
return &rule{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) in(path ...string) *rule {
|
func (r *rule) In(path ...string) Rule {
|
||||||
r.paths = append(r.paths, cleanPaths(path)...)
|
r.paths = append(r.paths, cleanPaths(path)...)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) notIn(path ...string) *rule {
|
func (r *rule) NotIn(path ...string) Rule {
|
||||||
r.unlessPaths = append(r.unlessPaths, cleanPaths(path)...)
|
r.unlessPaths = append(r.unlessPaths, cleanPaths(path)...)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) moduleType(types ...string) *rule {
|
func (r *rule) ModuleType(types ...string) Rule {
|
||||||
r.moduleTypes = append(r.moduleTypes, types...)
|
r.moduleTypes = append(r.moduleTypes, types...)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) notModuleType(types ...string) *rule {
|
func (r *rule) NotModuleType(types ...string) Rule {
|
||||||
r.unlessModuleTypes = append(r.unlessModuleTypes, types...)
|
r.unlessModuleTypes = append(r.unlessModuleTypes, types...)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) with(properties, value string) *rule {
|
func (r *rule) With(properties, value string) Rule {
|
||||||
r.props = append(r.props, ruleProperty{
|
r.props = append(r.props, ruleProperty{
|
||||||
fields: fieldNamesForProperties(properties),
|
fields: fieldNamesForProperties(properties),
|
||||||
value: value,
|
value: value,
|
||||||
@@ -212,7 +234,7 @@ func (r *rule) with(properties, value string) *rule {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) without(properties, value string) *rule {
|
func (r *rule) Without(properties, value string) Rule {
|
||||||
r.unlessProps = append(r.unlessProps, ruleProperty{
|
r.unlessProps = append(r.unlessProps, ruleProperty{
|
||||||
fields: fieldNamesForProperties(properties),
|
fields: fieldNamesForProperties(properties),
|
||||||
value: value,
|
value: value,
|
||||||
@@ -220,7 +242,7 @@ func (r *rule) without(properties, value string) *rule {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rule) because(reason string) *rule {
|
func (r *rule) Because(reason string) Rule {
|
||||||
r.reason = reason
|
r.reason = reason
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user