Add neverallow rules for java_device_for_host

java_device_for_host and java_host_for_device should rarely be
used and could cause problems if used incorrectly, so restrict them
to only the necessary projects through a neverallow whitelist.

Bug: 117920228
Test: neverallow_test.go
Change-Id: I37dce489c2fb8bca71bd46dbabaaa514bf6f7eee
Merged-In: I37dce489c2fb8bca71bd46dbabaaa514bf6f7eee
This commit is contained in:
Colin Cross 2019-03-05 15:06:16 -08:00
parent 3d7c9827d5
commit c35c5f9824
2 changed files with 59 additions and 0 deletions

View File

@ -51,6 +51,7 @@ func createNeverAllows() []*rule {
rules := []*rule{} rules := []*rule{}
rules = append(rules, createTrebleRules()...) rules = append(rules, createTrebleRules()...)
rules = append(rules, createLibcoreRules()...) rules = append(rules, createLibcoreRules()...)
rules = append(rules, createJavaDeviceForHostRules()...)
return rules return rules
} }
@ -125,6 +126,20 @@ func createLibcoreRules() []*rule {
return rules return rules
} }
func createJavaDeviceForHostRules() []*rule {
javaDeviceForHostProjectsWhitelist := []string{
"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"),
}
}
func neverallowMutator(ctx BottomUpMutatorContext) { func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module) m, ok := ctx.Module().(Module)
if !ok { if !ok {
@ -139,6 +154,10 @@ func neverallowMutator(ctx BottomUpMutatorContext) {
continue continue
} }
if !n.appliesToModuleType(ctx.ModuleType()) {
continue
}
if !n.appliesToProperties(properties) { if !n.appliesToProperties(properties) {
continue continue
} }
@ -159,6 +178,9 @@ type rule struct {
paths []string paths []string
unlessPaths []string unlessPaths []string
moduleTypes []string
unlessModuleTypes []string
props []ruleProperty props []ruleProperty
unlessProps []ruleProperty unlessProps []ruleProperty
} }
@ -166,14 +188,27 @@ type rule struct {
func 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 {
r.moduleTypes = append(r.moduleTypes, types...)
return r
}
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{ r.props = append(r.props, ruleProperty{
fields: fieldNamesForProperties(properties), fields: fieldNamesForProperties(properties),
@ -181,6 +216,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),
@ -188,6 +224,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
@ -201,6 +238,12 @@ func (r *rule) String() string {
for _, v := range r.unlessPaths { for _, v := range r.unlessPaths {
s += " -dir:" + v + "*" s += " -dir:" + v + "*"
} }
for _, v := range r.moduleTypes {
s += " type:" + v
}
for _, v := range r.unlessModuleTypes {
s += " -type:" + v
}
for _, v := range r.props { for _, v := range r.props {
s += " " + strings.Join(v.fields, ".") + "=" + v.value s += " " + strings.Join(v.fields, ".") + "=" + v.value
} }
@ -219,6 +262,10 @@ func (r *rule) appliesToPath(dir string) bool {
return includePath && !excludePath return includePath && !excludePath
} }
func (r *rule) appliesToModuleType(moduleType string) bool {
return (len(r.moduleTypes) == 0 || InList(moduleType, r.moduleTypes)) && !InList(moduleType, r.unlessModuleTypes)
}
func (r *rule) appliesToProperties(properties []interface{}) bool { func (r *rule) appliesToProperties(properties []interface{}) bool {
includeProps := hasAllProperties(properties, r.props) includeProps := hasAllProperties(properties, r.props)
excludeProps := hasAnyProperty(properties, r.unlessProps) excludeProps := hasAnyProperty(properties, r.unlessProps)

View File

@ -148,6 +148,17 @@ var neverallowTests = []struct {
}, },
expectedError: "Only core libraries projects can depend on core-libart", expectedError: "Only core libraries projects can depend on core-libart",
}, },
{
name: "java_device_for_host",
fs: map[string][]byte{
"Blueprints": []byte(`
java_device_for_host {
name: "device_for_host",
libs: ["core-libart"],
}`),
},
expectedError: "java_device_for_host can only be used in whitelisted projects",
},
} }
func TestNeverallow(t *testing.T) { func TestNeverallow(t *testing.T) {
@ -176,6 +187,7 @@ func testNeverallow(t *testing.T, config Config, fs map[string][]byte) (*TestCon
ctx := NewTestContext() ctx := NewTestContext()
ctx.RegisterModuleType("cc_library", ModuleFactoryAdaptor(newMockCcLibraryModule)) ctx.RegisterModuleType("cc_library", ModuleFactoryAdaptor(newMockCcLibraryModule))
ctx.RegisterModuleType("java_library", ModuleFactoryAdaptor(newMockJavaLibraryModule)) ctx.RegisterModuleType("java_library", ModuleFactoryAdaptor(newMockJavaLibraryModule))
ctx.RegisterModuleType("java_device_for_host", ModuleFactoryAdaptor(newMockJavaLibraryModule))
ctx.PostDepsMutators(registerNeverallowMutator) ctx.PostDepsMutators(registerNeverallowMutator)
ctx.Register() ctx.Register()