From 2ac2befc9ae5d461fda9434c553ee911fecaa4db Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Tue, 16 Jul 2019 14:18:22 +0100 Subject: [PATCH] Prevent runtime module paths being used in include_dirs Adds a new StartsWith(string) ValueMatcher along with With[Out]Matcher(...) methods to support new restrictions that prevent any paths into runtime module repositories from being added to the include_dirs. Test: m nothing Bug: 35624006 Change-Id: Ib954998e5fc190d8a11a8c6ac5f810cad927aac3 --- android/neverallow.go | 69 ++++++++++++++++++++++++++++++++++++-- android/neverallow_test.go | 24 +++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/android/neverallow.go b/android/neverallow.go index b8a01972e..23b645413 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -48,6 +48,7 @@ func registerNeverallowMutator(ctx RegisterMutatorsContext) { var neverallows = []Rule{} func init() { + AddNeverAllowRules(createIncludeDirsRules()...) AddNeverAllowRules(createTrebleRules()...) AddNeverAllowRules(createLibcoreRules()...) AddNeverAllowRules(createJavaDeviceForHostRules()...) @@ -58,6 +59,42 @@ func AddNeverAllowRules(rules ...Rule) { neverallows = append(neverallows, rules...) } +func createIncludeDirsRules() []Rule { + // The list of paths that cannot be referenced using include_dirs + paths := []string{ + "art", + "libcore", + "libnativehelper", + "external/apache-harmony", + "external/apache-xml", + "external/boringssl", + "external/bouncycastle", + "external/conscrypt", + "external/icu", + "external/okhttp", + "external/vixl", + "external/wycheproof", + "system/core/libnativebridge", + "system/core/libnativehelper", + } + + // Create a composite matcher that will match if the value starts with any of the restricted + // paths. A / is appended to the prefix to ensure that restricting path X does not affect paths + // XY. + rules := make([]Rule, 0, len(paths)) + for _, path := range paths { + rule := + NeverAllow(). + WithMatcher("include_dirs", StartsWith(path+"/")). + Because("include_dirs is deprecated, all usages of '" + path + "' have been migrated" + + " to use alternate mechanisms and so can no longer be used.") + + rules = append(rules, rule) + } + + return rules +} + func createTrebleRules() []Rule { return []Rule{ NeverAllow(). @@ -186,6 +223,18 @@ func (m *anyMatcher) String() string { var anyMatcherInstance = &anyMatcher{} +type startsWithMatcher struct { + prefix string +} + +func (m *startsWithMatcher) test(value string) bool { + return strings.HasPrefix(value, m.prefix) +} + +func (m *startsWithMatcher) String() string { + return ".starts-with(" + m.prefix + ")" +} + type ruleProperty struct { fields []string // e.x.: Vndk.Enabled matcher ValueMatcher @@ -203,8 +252,12 @@ type Rule interface { With(properties, value string) Rule + WithMatcher(properties string, matcher ValueMatcher) Rule + Without(properties, value string) Rule + WithoutMatcher(properties string, matcher ValueMatcher) Rule + Because(reason string) Rule } @@ -248,17 +301,25 @@ func (r *rule) NotModuleType(types ...string) Rule { } func (r *rule) With(properties, value string) Rule { + return r.WithMatcher(properties, selectMatcher(value)) +} + +func (r *rule) WithMatcher(properties string, matcher ValueMatcher) Rule { r.props = append(r.props, ruleProperty{ fields: fieldNamesForProperties(properties), - matcher: selectMatcher(value), + matcher: matcher, }) return r } func (r *rule) Without(properties, value string) Rule { + return r.WithoutMatcher(properties, selectMatcher(value)) +} + +func (r *rule) WithoutMatcher(properties string, matcher ValueMatcher) Rule { r.unlessProps = append(r.unlessProps, ruleProperty{ fields: fieldNamesForProperties(properties), - matcher: selectMatcher(value), + matcher: matcher, }) return r } @@ -317,6 +378,10 @@ func (r *rule) appliesToProperties(properties []interface{}) bool { return includeProps && !excludeProps } +func StartsWith(prefix string) ValueMatcher { + return &startsWithMatcher{prefix} +} + // assorted utils func cleanPaths(paths []string) []string { diff --git a/android/neverallow_test.go b/android/neverallow_test.go index ee3c94f0c..02b436211 100644 --- a/android/neverallow_test.go +++ b/android/neverallow_test.go @@ -23,6 +23,29 @@ var neverallowTests = []struct { fs map[string][]byte expectedError string }{ + // include_dir rule tests + { + name: "include_dir not allowed to reference art", + fs: map[string][]byte{ + "other/Blueprints": []byte(` + cc_library { + name: "libother", + include_dirs: ["art/libdexfile/include"], + }`), + }, + expectedError: "all usages of 'art' have been migrated", + }, + { + name: "include_dir can reference another location", + fs: map[string][]byte{ + "other/Blueprints": []byte(` + cc_library { + name: "libother", + include_dirs: ["another/include"], + }`), + }, + }, + // Treble rule tests { name: "no vndk.enabled under vendor directory", fs: map[string][]byte{ @@ -217,6 +240,7 @@ func testNeverallow(t *testing.T, config Config, fs map[string][]byte) (*TestCon } type mockCcLibraryProperties struct { + Include_dirs []string Vendor_available *bool Vndk struct {