1*333d2b36SAndroid Build Coastguard Worker// Copyright 2017 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage android 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "fmt" 19*333d2b36SAndroid Build Coastguard Worker "path/filepath" 20*333d2b36SAndroid Build Coastguard Worker "reflect" 21*333d2b36SAndroid Build Coastguard Worker "regexp" 22*333d2b36SAndroid Build Coastguard Worker "strconv" 23*333d2b36SAndroid Build Coastguard Worker "strings" 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 26*333d2b36SAndroid Build Coastguard Worker) 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Worker// "neverallow" rules for the build system. 29*333d2b36SAndroid Build Coastguard Worker// 30*333d2b36SAndroid Build Coastguard Worker// This allows things which aren't related to the build system and are enforced 31*333d2b36SAndroid Build Coastguard Worker// against assumptions, in progress code refactors, or policy to be expressed in a 32*333d2b36SAndroid Build Coastguard Worker// straightforward away disjoint from implementations and tests which should 33*333d2b36SAndroid Build Coastguard Worker// work regardless of these restrictions. 34*333d2b36SAndroid Build Coastguard Worker// 35*333d2b36SAndroid Build Coastguard Worker// A module is disallowed if all of the following are true: 36*333d2b36SAndroid Build Coastguard Worker// - it is in one of the "In" paths 37*333d2b36SAndroid Build Coastguard Worker// - it is not in one of the "NotIn" paths 38*333d2b36SAndroid Build Coastguard Worker// - it has all "With" properties matched 39*333d2b36SAndroid Build Coastguard Worker// - - values are matched in their entirety 40*333d2b36SAndroid Build Coastguard Worker// - - nil is interpreted as an empty string 41*333d2b36SAndroid Build Coastguard Worker// - - nested properties are separated with a '.' 42*333d2b36SAndroid Build Coastguard Worker// - - if the property is a list, any of the values in the list being matches 43*333d2b36SAndroid Build Coastguard Worker// counts as a match 44*333d2b36SAndroid Build Coastguard Worker// - it has none of the "Without" properties matched (same rules as above) 45*333d2b36SAndroid Build Coastguard Worker 46*333d2b36SAndroid Build Coastguard Workerfunc registerNeverallowMutator(ctx RegisterMutatorsContext) { 47*333d2b36SAndroid Build Coastguard Worker ctx.BottomUp("neverallow", neverallowMutator) 48*333d2b36SAndroid Build Coastguard Worker} 49*333d2b36SAndroid Build Coastguard Worker 50*333d2b36SAndroid Build Coastguard Workervar neverallows = []Rule{} 51*333d2b36SAndroid Build Coastguard Worker 52*333d2b36SAndroid Build Coastguard Workerfunc init() { 53*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createIncludeDirsRules()...) 54*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createTrebleRules()...) 55*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createJavaDeviceForHostRules()...) 56*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createCcSdkVariantRules()...) 57*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createUncompressDexRules()...) 58*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createInstallInRootAllowingRules()...) 59*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createProhibitFrameworkAccessRules()...) 60*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createCcStubsRule()) 61*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createProhibitHeaderOnlyRule()) 62*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createLimitNdkExportRule()...) 63*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createLimitDirgroupRule()...) 64*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createFilesystemIsAutoGeneratedRule()) 65*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createKotlinPluginRule()...) 66*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createPrebuiltEtcBpDefineRule()) 67*333d2b36SAndroid Build Coastguard Worker AddNeverAllowRules(createAutogenRroBpDefineRule()) 68*333d2b36SAndroid Build Coastguard Worker} 69*333d2b36SAndroid Build Coastguard Worker 70*333d2b36SAndroid Build Coastguard Worker// Add a NeverAllow rule to the set of rules to apply. 71*333d2b36SAndroid Build Coastguard Workerfunc AddNeverAllowRules(rules ...Rule) { 72*333d2b36SAndroid Build Coastguard Worker neverallows = append(neverallows, rules...) 73*333d2b36SAndroid Build Coastguard Worker} 74*333d2b36SAndroid Build Coastguard Worker 75*333d2b36SAndroid Build Coastguard Workervar ( 76*333d2b36SAndroid Build Coastguard Worker neverallowNotInIncludeDir = []string{ 77*333d2b36SAndroid Build Coastguard Worker "art", 78*333d2b36SAndroid Build Coastguard Worker "art/libnativebridge", 79*333d2b36SAndroid Build Coastguard Worker "art/libnativeloader", 80*333d2b36SAndroid Build Coastguard Worker "libcore", 81*333d2b36SAndroid Build Coastguard Worker "libnativehelper", 82*333d2b36SAndroid Build Coastguard Worker "external/apache-harmony", 83*333d2b36SAndroid Build Coastguard Worker "external/apache-xml", 84*333d2b36SAndroid Build Coastguard Worker "external/boringssl", 85*333d2b36SAndroid Build Coastguard Worker "external/bouncycastle", 86*333d2b36SAndroid Build Coastguard Worker "external/conscrypt", 87*333d2b36SAndroid Build Coastguard Worker "external/icu", 88*333d2b36SAndroid Build Coastguard Worker "external/okhttp", 89*333d2b36SAndroid Build Coastguard Worker "external/vixl", 90*333d2b36SAndroid Build Coastguard Worker "external/wycheproof", 91*333d2b36SAndroid Build Coastguard Worker } 92*333d2b36SAndroid Build Coastguard Worker neverallowNoUseIncludeDir = []string{ 93*333d2b36SAndroid Build Coastguard Worker "frameworks/av/apex", 94*333d2b36SAndroid Build Coastguard Worker "frameworks/av/tools", 95*333d2b36SAndroid Build Coastguard Worker "frameworks/native/cmds", 96*333d2b36SAndroid Build Coastguard Worker "system/apex", 97*333d2b36SAndroid Build Coastguard Worker "system/bpf", 98*333d2b36SAndroid Build Coastguard Worker "system/gatekeeper", 99*333d2b36SAndroid Build Coastguard Worker "system/hwservicemanager", 100*333d2b36SAndroid Build Coastguard Worker "system/libbase", 101*333d2b36SAndroid Build Coastguard Worker "system/libfmq", 102*333d2b36SAndroid Build Coastguard Worker "system/libvintf", 103*333d2b36SAndroid Build Coastguard Worker } 104*333d2b36SAndroid Build Coastguard Worker) 105*333d2b36SAndroid Build Coastguard Worker 106*333d2b36SAndroid Build Coastguard Workerfunc createIncludeDirsRules() []Rule { 107*333d2b36SAndroid Build Coastguard Worker rules := make([]Rule, 0, len(neverallowNotInIncludeDir)+len(neverallowNoUseIncludeDir)) 108*333d2b36SAndroid Build Coastguard Worker 109*333d2b36SAndroid Build Coastguard Worker for _, path := range neverallowNotInIncludeDir { 110*333d2b36SAndroid Build Coastguard Worker rule := 111*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 112*333d2b36SAndroid Build Coastguard Worker WithMatcher("include_dirs", StartsWith(path+"/")). 113*333d2b36SAndroid Build Coastguard Worker Because("include_dirs is deprecated, all usages of '" + path + "' have been migrated" + 114*333d2b36SAndroid Build Coastguard Worker " to use alternate mechanisms and so can no longer be used.") 115*333d2b36SAndroid Build Coastguard Worker 116*333d2b36SAndroid Build Coastguard Worker rules = append(rules, rule) 117*333d2b36SAndroid Build Coastguard Worker } 118*333d2b36SAndroid Build Coastguard Worker 119*333d2b36SAndroid Build Coastguard Worker for _, path := range neverallowNoUseIncludeDir { 120*333d2b36SAndroid Build Coastguard Worker rule := NeverAllow().In(path+"/").WithMatcher("include_dirs", isSetMatcherInstance). 121*333d2b36SAndroid Build Coastguard Worker Because("include_dirs is deprecated, all usages of them in '" + path + "' have been migrated" + 122*333d2b36SAndroid Build Coastguard Worker " to use alternate mechanisms and so can no longer be used.") 123*333d2b36SAndroid Build Coastguard Worker rules = append(rules, rule) 124*333d2b36SAndroid Build Coastguard Worker } 125*333d2b36SAndroid Build Coastguard Worker 126*333d2b36SAndroid Build Coastguard Worker return rules 127*333d2b36SAndroid Build Coastguard Worker} 128*333d2b36SAndroid Build Coastguard Worker 129*333d2b36SAndroid Build Coastguard Workerfunc createTrebleRules() []Rule { 130*333d2b36SAndroid Build Coastguard Worker return []Rule{ 131*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 132*333d2b36SAndroid Build Coastguard Worker In("vendor", "device"). 133*333d2b36SAndroid Build Coastguard Worker With("vndk.enabled", "true"). 134*333d2b36SAndroid Build Coastguard Worker Without("vendor", "true"). 135*333d2b36SAndroid Build Coastguard Worker Without("product_specific", "true"). 136*333d2b36SAndroid Build Coastguard Worker Because("the VNDK can never contain a library that is device dependent."), 137*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 138*333d2b36SAndroid Build Coastguard Worker With("vndk.enabled", "true"). 139*333d2b36SAndroid Build Coastguard Worker Without("vendor", "true"). 140*333d2b36SAndroid Build Coastguard Worker Without("owner", ""). 141*333d2b36SAndroid Build Coastguard Worker Because("a VNDK module can never have an owner."), 142*333d2b36SAndroid Build Coastguard Worker 143*333d2b36SAndroid Build Coastguard Worker // TODO(b/67974785): always enforce the manifest 144*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 145*333d2b36SAndroid Build Coastguard Worker Without("name", "libhidlbase-combined-impl"). 146*333d2b36SAndroid Build Coastguard Worker Without("name", "libhidlbase"). 147*333d2b36SAndroid Build Coastguard Worker With("product_variables.enforce_vintf_manifest.cflags", "*"). 148*333d2b36SAndroid Build Coastguard Worker Because("manifest enforcement should be independent of ."), 149*333d2b36SAndroid Build Coastguard Worker 150*333d2b36SAndroid Build Coastguard Worker // TODO(b/67975799): vendor code should always use /vendor/bin/sh 151*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 152*333d2b36SAndroid Build Coastguard Worker Without("name", "libc_bionic_ndk"). 153*333d2b36SAndroid Build Coastguard Worker With("product_variables.treble_linker_namespaces.cflags", "*"). 154*333d2b36SAndroid Build Coastguard Worker Because("nothing should care if linker namespaces are enabled or not"), 155*333d2b36SAndroid Build Coastguard Worker 156*333d2b36SAndroid Build Coastguard Worker // Example: 157*333d2b36SAndroid Build Coastguard Worker // *NeverAllow().with("Srcs", "main.cpp")) 158*333d2b36SAndroid Build Coastguard Worker } 159*333d2b36SAndroid Build Coastguard Worker} 160*333d2b36SAndroid Build Coastguard Worker 161*333d2b36SAndroid Build Coastguard Workerfunc createJavaDeviceForHostRules() []Rule { 162*333d2b36SAndroid Build Coastguard Worker javaDeviceForHostProjectsAllowedList := []string{ 163*333d2b36SAndroid Build Coastguard Worker "development/build", 164*333d2b36SAndroid Build Coastguard Worker "external/guava", 165*333d2b36SAndroid Build Coastguard Worker "external/kotlinx.coroutines", 166*333d2b36SAndroid Build Coastguard Worker "external/robolectric-shadows", 167*333d2b36SAndroid Build Coastguard Worker "external/robolectric", 168*333d2b36SAndroid Build Coastguard Worker "frameworks/base/ravenwood", 169*333d2b36SAndroid Build Coastguard Worker "frameworks/base/tools/hoststubgen", 170*333d2b36SAndroid Build Coastguard Worker "frameworks/layoutlib", 171*333d2b36SAndroid Build Coastguard Worker } 172*333d2b36SAndroid Build Coastguard Worker 173*333d2b36SAndroid Build Coastguard Worker return []Rule{ 174*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 175*333d2b36SAndroid Build Coastguard Worker NotIn(javaDeviceForHostProjectsAllowedList...). 176*333d2b36SAndroid Build Coastguard Worker ModuleType("java_device_for_host", "java_host_for_device"). 177*333d2b36SAndroid Build Coastguard Worker Because("java_device_for_host can only be used in allowed projects"), 178*333d2b36SAndroid Build Coastguard Worker } 179*333d2b36SAndroid Build Coastguard Worker} 180*333d2b36SAndroid Build Coastguard Worker 181*333d2b36SAndroid Build Coastguard Workerfunc createCcSdkVariantRules() []Rule { 182*333d2b36SAndroid Build Coastguard Worker sdkVersionOnlyAllowedList := []string{ 183*333d2b36SAndroid Build Coastguard Worker // derive_sdk_prefer32 has stem: "derive_sdk" which conflicts with the derive_sdk. 184*333d2b36SAndroid Build Coastguard Worker // This sometimes works because the APEX modules that contain derive_sdk and 185*333d2b36SAndroid Build Coastguard Worker // derive_sdk_prefer32 suppress the platform installation rules, but fails when 186*333d2b36SAndroid Build Coastguard Worker // the APEX modules contain the SDK variant and the platform variant still exists. 187*333d2b36SAndroid Build Coastguard Worker "packages/modules/SdkExtensions/derive_sdk", 188*333d2b36SAndroid Build Coastguard Worker // These are for apps and shouldn't be used by non-SDK variant modules. 189*333d2b36SAndroid Build Coastguard Worker "prebuilts/ndk", 190*333d2b36SAndroid Build Coastguard Worker "frameworks/native/libs/binder/ndk", 191*333d2b36SAndroid Build Coastguard Worker "tools/test/graphicsbenchmark/apps/sample_app", 192*333d2b36SAndroid Build Coastguard Worker "tools/test/graphicsbenchmark/functional_tests/java", 193*333d2b36SAndroid Build Coastguard Worker "vendor/xts/gts-tests/hostsidetests/gamedevicecert/apps/javatests", 194*333d2b36SAndroid Build Coastguard Worker "external/libtextclassifier/native", 195*333d2b36SAndroid Build Coastguard Worker } 196*333d2b36SAndroid Build Coastguard Worker 197*333d2b36SAndroid Build Coastguard Worker platformVariantPropertiesAllowedList := []string{ 198*333d2b36SAndroid Build Coastguard Worker // android_native_app_glue and libRSSupport use native_window.h but target old 199*333d2b36SAndroid Build Coastguard Worker // sdk versions (minimum and 9 respectively) where libnativewindow didn't exist, 200*333d2b36SAndroid Build Coastguard Worker // so they can't add libnativewindow to shared_libs to get the header directory 201*333d2b36SAndroid Build Coastguard Worker // for the platform variant. Allow them to use the platform variant 202*333d2b36SAndroid Build Coastguard Worker // property to set shared_libs. 203*333d2b36SAndroid Build Coastguard Worker "prebuilts/ndk", 204*333d2b36SAndroid Build Coastguard Worker "frameworks/rs", 205*333d2b36SAndroid Build Coastguard Worker } 206*333d2b36SAndroid Build Coastguard Worker 207*333d2b36SAndroid Build Coastguard Worker return []Rule{ 208*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 209*333d2b36SAndroid Build Coastguard Worker NotIn(sdkVersionOnlyAllowedList...). 210*333d2b36SAndroid Build Coastguard Worker WithMatcher("sdk_variant_only", isSetMatcherInstance). 211*333d2b36SAndroid Build Coastguard Worker Because("sdk_variant_only can only be used in allowed projects"), 212*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 213*333d2b36SAndroid Build Coastguard Worker NotIn(platformVariantPropertiesAllowedList...). 214*333d2b36SAndroid Build Coastguard Worker WithMatcher("platform.shared_libs", isSetMatcherInstance). 215*333d2b36SAndroid Build Coastguard Worker Because("platform variant properties can only be used in allowed projects"), 216*333d2b36SAndroid Build Coastguard Worker } 217*333d2b36SAndroid Build Coastguard Worker} 218*333d2b36SAndroid Build Coastguard Worker 219*333d2b36SAndroid Build Coastguard Workerfunc createCcStubsRule() Rule { 220*333d2b36SAndroid Build Coastguard Worker ccStubsImplementationInstallableProjectsAllowedList := []string{ 221*333d2b36SAndroid Build Coastguard Worker "packages/modules/Virtualization/libs/libvm_payload", 222*333d2b36SAndroid Build Coastguard Worker } 223*333d2b36SAndroid Build Coastguard Worker 224*333d2b36SAndroid Build Coastguard Worker return NeverAllow(). 225*333d2b36SAndroid Build Coastguard Worker NotIn(ccStubsImplementationInstallableProjectsAllowedList...). 226*333d2b36SAndroid Build Coastguard Worker WithMatcher("stubs.implementation_installable", isSetMatcherInstance). 227*333d2b36SAndroid Build Coastguard Worker Because("implementation_installable can only be used in allowed projects.") 228*333d2b36SAndroid Build Coastguard Worker} 229*333d2b36SAndroid Build Coastguard Worker 230*333d2b36SAndroid Build Coastguard Workerfunc createUncompressDexRules() []Rule { 231*333d2b36SAndroid Build Coastguard Worker return []Rule{ 232*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 233*333d2b36SAndroid Build Coastguard Worker NotIn("art"). 234*333d2b36SAndroid Build Coastguard Worker WithMatcher("uncompress_dex", isSetMatcherInstance). 235*333d2b36SAndroid Build Coastguard Worker Because("uncompress_dex is only allowed for certain jars for test in art."), 236*333d2b36SAndroid Build Coastguard Worker } 237*333d2b36SAndroid Build Coastguard Worker} 238*333d2b36SAndroid Build Coastguard Worker 239*333d2b36SAndroid Build Coastguard Workerfunc createInstallInRootAllowingRules() []Rule { 240*333d2b36SAndroid Build Coastguard Worker return []Rule{ 241*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 242*333d2b36SAndroid Build Coastguard Worker Without("name", "init_first_stage_defaults"). 243*333d2b36SAndroid Build Coastguard Worker Without("name", "init_first_stage"). 244*333d2b36SAndroid Build Coastguard Worker Without("name", "init_first_stage.microdroid"). 245*333d2b36SAndroid Build Coastguard Worker Without("name", "librecovery_ui_ext"). 246*333d2b36SAndroid Build Coastguard Worker With("install_in_root", "true"). 247*333d2b36SAndroid Build Coastguard Worker NotModuleType("prebuilt_root"). 248*333d2b36SAndroid Build Coastguard Worker NotModuleType("prebuilt_vendor"). 249*333d2b36SAndroid Build Coastguard Worker NotModuleType("prebuilt_sbin"). 250*333d2b36SAndroid Build Coastguard Worker NotModuleType("prebuilt_system"). 251*333d2b36SAndroid Build Coastguard Worker NotModuleType("prebuilt_first_stage_ramdisk"). 252*333d2b36SAndroid Build Coastguard Worker NotModuleType("prebuilt_res"). 253*333d2b36SAndroid Build Coastguard Worker Because("install_in_root is only for init_first_stage or librecovery_ui_ext."), 254*333d2b36SAndroid Build Coastguard Worker } 255*333d2b36SAndroid Build Coastguard Worker} 256*333d2b36SAndroid Build Coastguard Worker 257*333d2b36SAndroid Build Coastguard Workerfunc createProhibitFrameworkAccessRules() []Rule { 258*333d2b36SAndroid Build Coastguard Worker return []Rule{ 259*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 260*333d2b36SAndroid Build Coastguard Worker With("libs", "framework"). 261*333d2b36SAndroid Build Coastguard Worker WithoutMatcher("sdk_version", Regexp("(core_.*|^$)")). 262*333d2b36SAndroid Build Coastguard Worker Because("framework can't be used when building against SDK"), 263*333d2b36SAndroid Build Coastguard Worker } 264*333d2b36SAndroid Build Coastguard Worker} 265*333d2b36SAndroid Build Coastguard Worker 266*333d2b36SAndroid Build Coastguard Workerfunc createProhibitHeaderOnlyRule() Rule { 267*333d2b36SAndroid Build Coastguard Worker return NeverAllow(). 268*333d2b36SAndroid Build Coastguard Worker Without("name", "framework-minus-apex-headers"). 269*333d2b36SAndroid Build Coastguard Worker With("headers_only", "true"). 270*333d2b36SAndroid Build Coastguard Worker Because("headers_only can only be used for generating framework-minus-apex headers for non-updatable modules") 271*333d2b36SAndroid Build Coastguard Worker} 272*333d2b36SAndroid Build Coastguard Worker 273*333d2b36SAndroid Build Coastguard Workerfunc createLimitNdkExportRule() []Rule { 274*333d2b36SAndroid Build Coastguard Worker reason := "If the headers you're trying to export are meant to be a part of the NDK, they should be exposed by an ndk_headers module. If the headers shouldn't be a part of the NDK, the headers should instead be exposed from a separate `cc_library_headers` which consumers depend on." 275*333d2b36SAndroid Build Coastguard Worker // DO NOT ADD HERE - please consult danalbert@ 276*333d2b36SAndroid Build Coastguard Worker // b/357711733 277*333d2b36SAndroid Build Coastguard Worker return []Rule{ 278*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 279*333d2b36SAndroid Build Coastguard Worker NotIn("frameworks/native/libs/binder/ndk"). 280*333d2b36SAndroid Build Coastguard Worker ModuleType("ndk_library"). 281*333d2b36SAndroid Build Coastguard Worker WithMatcher("export_header_libs", isSetMatcherInstance).Because(reason), 282*333d2b36SAndroid Build Coastguard Worker NeverAllow().ModuleType("ndk_library").WithMatcher("export_generated_headers", isSetMatcherInstance).Because(reason), 283*333d2b36SAndroid Build Coastguard Worker NeverAllow().ModuleType("ndk_library").WithMatcher("export_include_dirs", isSetMatcherInstance).Because(reason), 284*333d2b36SAndroid Build Coastguard Worker NeverAllow().ModuleType("ndk_library").WithMatcher("export_shared_lib_headers", isSetMatcherInstance).Because(reason), 285*333d2b36SAndroid Build Coastguard Worker NeverAllow().ModuleType("ndk_library").WithMatcher("export_static_lib_headers", isSetMatcherInstance).Because(reason), 286*333d2b36SAndroid Build Coastguard Worker } 287*333d2b36SAndroid Build Coastguard Worker} 288*333d2b36SAndroid Build Coastguard Worker 289*333d2b36SAndroid Build Coastguard Workerfunc createLimitDirgroupRule() []Rule { 290*333d2b36SAndroid Build Coastguard Worker reason := "dirgroup module and dir_srcs / keep_gendir property of genrule is allowed only to Trusty build rule." 291*333d2b36SAndroid Build Coastguard Worker return []Rule{ 292*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 293*333d2b36SAndroid Build Coastguard Worker ModuleType("dirgroup"). 294*333d2b36SAndroid Build Coastguard Worker WithMatcher("visibility", NotInList([]string{"//trusty/vendor/google/aosp/scripts"})).Because(reason), 295*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 296*333d2b36SAndroid Build Coastguard Worker ModuleType("dirgroup"). 297*333d2b36SAndroid Build Coastguard Worker Without("visibility", "//trusty/vendor/google/aosp/scripts").Because(reason), 298*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 299*333d2b36SAndroid Build Coastguard Worker ModuleType("genrule"). 300*333d2b36SAndroid Build Coastguard Worker Without("name", "trusty-arm64.lk.elf.gen"). 301*333d2b36SAndroid Build Coastguard Worker Without("name", "trusty-arm64-virt-test-debug.lk.elf.gen"). 302*333d2b36SAndroid Build Coastguard Worker Without("name", "trusty-x86_64.lk.elf.gen"). 303*333d2b36SAndroid Build Coastguard Worker Without("name", "trusty-x86_64-test.lk.elf.gen"). 304*333d2b36SAndroid Build Coastguard Worker WithMatcher("dir_srcs", isSetMatcherInstance).Because(reason), 305*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 306*333d2b36SAndroid Build Coastguard Worker ModuleType("genrule"). 307*333d2b36SAndroid Build Coastguard Worker Without("name", "trusty-arm64.lk.elf.gen"). 308*333d2b36SAndroid Build Coastguard Worker Without("name", "trusty-arm64-virt-test-debug.lk.elf.gen"). 309*333d2b36SAndroid Build Coastguard Worker Without("name", "trusty-x86_64.lk.elf.gen"). 310*333d2b36SAndroid Build Coastguard Worker Without("name", "trusty-x86_64-test.lk.elf.gen"). 311*333d2b36SAndroid Build Coastguard Worker With("keep_gendir", "true").Because(reason), 312*333d2b36SAndroid Build Coastguard Worker } 313*333d2b36SAndroid Build Coastguard Worker} 314*333d2b36SAndroid Build Coastguard Worker 315*333d2b36SAndroid Build Coastguard Workerfunc createFilesystemIsAutoGeneratedRule() Rule { 316*333d2b36SAndroid Build Coastguard Worker return NeverAllow(). 317*333d2b36SAndroid Build Coastguard Worker NotIn("build/soong/fsgen"). 318*333d2b36SAndroid Build Coastguard Worker ModuleType("filesystem", "android_system_image"). 319*333d2b36SAndroid Build Coastguard Worker WithMatcher("is_auto_generated", isSetMatcherInstance). 320*333d2b36SAndroid Build Coastguard Worker Because("is_auto_generated property is only allowed for filesystem modules in build/soong/fsgen directory") 321*333d2b36SAndroid Build Coastguard Worker} 322*333d2b36SAndroid Build Coastguard Worker 323*333d2b36SAndroid Build Coastguard Workerfunc createKotlinPluginRule() []Rule { 324*333d2b36SAndroid Build Coastguard Worker kotlinPluginProjectsAllowedList := []string{ 325*333d2b36SAndroid Build Coastguard Worker // TODO: Migrate compose plugin to the bundled compiler plugin 326*333d2b36SAndroid Build Coastguard Worker // Actual path prebuilts/sdk/current/androidx/m2repository/androidx/compose/compiler/compiler-hosted 327*333d2b36SAndroid Build Coastguard Worker "prebuilts/sdk/current/androidx", 328*333d2b36SAndroid Build Coastguard Worker "external/kotlinc", 329*333d2b36SAndroid Build Coastguard Worker } 330*333d2b36SAndroid Build Coastguard Worker 331*333d2b36SAndroid Build Coastguard Worker return []Rule{ 332*333d2b36SAndroid Build Coastguard Worker NeverAllow(). 333*333d2b36SAndroid Build Coastguard Worker NotIn(kotlinPluginProjectsAllowedList...). 334*333d2b36SAndroid Build Coastguard Worker ModuleType("kotlin_plugin"). 335*333d2b36SAndroid Build Coastguard Worker Because("kotlin_plugin can only be used in allowed projects"), 336*333d2b36SAndroid Build Coastguard Worker } 337*333d2b36SAndroid Build Coastguard Worker} 338*333d2b36SAndroid Build Coastguard Worker 339*333d2b36SAndroid Build Coastguard Worker// These module types are introduced to convert PRODUCT_COPY_FILES to Soong, 340*333d2b36SAndroid Build Coastguard Worker// and is only intended to be used by filesystem_creator. 341*333d2b36SAndroid Build Coastguard Workerfunc createPrebuiltEtcBpDefineRule() Rule { 342*333d2b36SAndroid Build Coastguard Worker return NeverAllow(). 343*333d2b36SAndroid Build Coastguard Worker ModuleType( 344*333d2b36SAndroid Build Coastguard Worker "prebuilt_usr_srec", 345*333d2b36SAndroid Build Coastguard Worker "prebuilt_priv_app", 346*333d2b36SAndroid Build Coastguard Worker "prebuilt_rfs", 347*333d2b36SAndroid Build Coastguard Worker "prebuilt_framework", 348*333d2b36SAndroid Build Coastguard Worker "prebuilt_wlc_upt", 349*333d2b36SAndroid Build Coastguard Worker "prebuilt_odm", 350*333d2b36SAndroid Build Coastguard Worker "prebuilt_vendor_dlkm", 351*333d2b36SAndroid Build Coastguard Worker "prebuilt_bt_firmware", 352*333d2b36SAndroid Build Coastguard Worker "prebuilt_tvservice", 353*333d2b36SAndroid Build Coastguard Worker "prebuilt_optee", 354*333d2b36SAndroid Build Coastguard Worker "prebuilt_tvconfig", 355*333d2b36SAndroid Build Coastguard Worker "prebuilt_vendor", 356*333d2b36SAndroid Build Coastguard Worker "prebuilt_sbin", 357*333d2b36SAndroid Build Coastguard Worker "prebuilt_system", 358*333d2b36SAndroid Build Coastguard Worker "prebuilt_first_stage_ramdisk", 359*333d2b36SAndroid Build Coastguard Worker ). 360*333d2b36SAndroid Build Coastguard Worker DefinedInBpFile(). 361*333d2b36SAndroid Build Coastguard Worker Because("module type not allowed to be defined in bp file") 362*333d2b36SAndroid Build Coastguard Worker} 363*333d2b36SAndroid Build Coastguard Worker 364*333d2b36SAndroid Build Coastguard Workerfunc createAutogenRroBpDefineRule() Rule { 365*333d2b36SAndroid Build Coastguard Worker return NeverAllow(). 366*333d2b36SAndroid Build Coastguard Worker ModuleType( 367*333d2b36SAndroid Build Coastguard Worker "autogen_runtime_resource_overlay", 368*333d2b36SAndroid Build Coastguard Worker ). 369*333d2b36SAndroid Build Coastguard Worker DefinedInBpFile(). 370*333d2b36SAndroid Build Coastguard Worker Because("Module type will be autogenerated by soong. Use runtime_resource_overlay instead") 371*333d2b36SAndroid Build Coastguard Worker} 372*333d2b36SAndroid Build Coastguard Worker 373*333d2b36SAndroid Build Coastguard Workerfunc neverallowMutator(ctx BottomUpMutatorContext) { 374*333d2b36SAndroid Build Coastguard Worker m, ok := ctx.Module().(Module) 375*333d2b36SAndroid Build Coastguard Worker if !ok { 376*333d2b36SAndroid Build Coastguard Worker return 377*333d2b36SAndroid Build Coastguard Worker } 378*333d2b36SAndroid Build Coastguard Worker 379*333d2b36SAndroid Build Coastguard Worker dir := ctx.ModuleDir() + "/" 380*333d2b36SAndroid Build Coastguard Worker properties := m.GetProperties() 381*333d2b36SAndroid Build Coastguard Worker 382*333d2b36SAndroid Build Coastguard Worker osClass := ctx.Module().Target().Os.Class 383*333d2b36SAndroid Build Coastguard Worker 384*333d2b36SAndroid Build Coastguard Worker for _, r := range neverallowRules(ctx.Config()) { 385*333d2b36SAndroid Build Coastguard Worker n := r.(*rule) 386*333d2b36SAndroid Build Coastguard Worker if !n.appliesToPath(dir) { 387*333d2b36SAndroid Build Coastguard Worker continue 388*333d2b36SAndroid Build Coastguard Worker } 389*333d2b36SAndroid Build Coastguard Worker 390*333d2b36SAndroid Build Coastguard Worker if !n.appliesToModuleType(ctx.ModuleType()) { 391*333d2b36SAndroid Build Coastguard Worker continue 392*333d2b36SAndroid Build Coastguard Worker } 393*333d2b36SAndroid Build Coastguard Worker 394*333d2b36SAndroid Build Coastguard Worker if !n.appliesToProperties(ctx, properties) { 395*333d2b36SAndroid Build Coastguard Worker continue 396*333d2b36SAndroid Build Coastguard Worker } 397*333d2b36SAndroid Build Coastguard Worker 398*333d2b36SAndroid Build Coastguard Worker if !n.appliesToOsClass(osClass) { 399*333d2b36SAndroid Build Coastguard Worker continue 400*333d2b36SAndroid Build Coastguard Worker } 401*333d2b36SAndroid Build Coastguard Worker 402*333d2b36SAndroid Build Coastguard Worker if !n.appliesToDirectDeps(ctx) { 403*333d2b36SAndroid Build Coastguard Worker continue 404*333d2b36SAndroid Build Coastguard Worker } 405*333d2b36SAndroid Build Coastguard Worker 406*333d2b36SAndroid Build Coastguard Worker if !n.appliesToBpDefinedModule(ctx) { 407*333d2b36SAndroid Build Coastguard Worker continue 408*333d2b36SAndroid Build Coastguard Worker } 409*333d2b36SAndroid Build Coastguard Worker 410*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("violates " + n.String()) 411*333d2b36SAndroid Build Coastguard Worker } 412*333d2b36SAndroid Build Coastguard Worker} 413*333d2b36SAndroid Build Coastguard Worker 414*333d2b36SAndroid Build Coastguard Workertype ValueMatcher interface { 415*333d2b36SAndroid Build Coastguard Worker Test(string) bool 416*333d2b36SAndroid Build Coastguard Worker String() string 417*333d2b36SAndroid Build Coastguard Worker} 418*333d2b36SAndroid Build Coastguard Worker 419*333d2b36SAndroid Build Coastguard Workertype equalMatcher struct { 420*333d2b36SAndroid Build Coastguard Worker expected string 421*333d2b36SAndroid Build Coastguard Worker} 422*333d2b36SAndroid Build Coastguard Worker 423*333d2b36SAndroid Build Coastguard Workerfunc (m *equalMatcher) Test(value string) bool { 424*333d2b36SAndroid Build Coastguard Worker return m.expected == value 425*333d2b36SAndroid Build Coastguard Worker} 426*333d2b36SAndroid Build Coastguard Worker 427*333d2b36SAndroid Build Coastguard Workerfunc (m *equalMatcher) String() string { 428*333d2b36SAndroid Build Coastguard Worker return "=" + m.expected 429*333d2b36SAndroid Build Coastguard Worker} 430*333d2b36SAndroid Build Coastguard Worker 431*333d2b36SAndroid Build Coastguard Workertype anyMatcher struct { 432*333d2b36SAndroid Build Coastguard Worker} 433*333d2b36SAndroid Build Coastguard Worker 434*333d2b36SAndroid Build Coastguard Workerfunc (m *anyMatcher) Test(value string) bool { 435*333d2b36SAndroid Build Coastguard Worker return true 436*333d2b36SAndroid Build Coastguard Worker} 437*333d2b36SAndroid Build Coastguard Worker 438*333d2b36SAndroid Build Coastguard Workerfunc (m *anyMatcher) String() string { 439*333d2b36SAndroid Build Coastguard Worker return "=*" 440*333d2b36SAndroid Build Coastguard Worker} 441*333d2b36SAndroid Build Coastguard Worker 442*333d2b36SAndroid Build Coastguard Workervar anyMatcherInstance = &anyMatcher{} 443*333d2b36SAndroid Build Coastguard Worker 444*333d2b36SAndroid Build Coastguard Workertype startsWithMatcher struct { 445*333d2b36SAndroid Build Coastguard Worker prefix string 446*333d2b36SAndroid Build Coastguard Worker} 447*333d2b36SAndroid Build Coastguard Worker 448*333d2b36SAndroid Build Coastguard Workerfunc (m *startsWithMatcher) Test(value string) bool { 449*333d2b36SAndroid Build Coastguard Worker return strings.HasPrefix(value, m.prefix) 450*333d2b36SAndroid Build Coastguard Worker} 451*333d2b36SAndroid Build Coastguard Worker 452*333d2b36SAndroid Build Coastguard Workerfunc (m *startsWithMatcher) String() string { 453*333d2b36SAndroid Build Coastguard Worker return ".starts-with(" + m.prefix + ")" 454*333d2b36SAndroid Build Coastguard Worker} 455*333d2b36SAndroid Build Coastguard Worker 456*333d2b36SAndroid Build Coastguard Workertype regexMatcher struct { 457*333d2b36SAndroid Build Coastguard Worker re *regexp.Regexp 458*333d2b36SAndroid Build Coastguard Worker} 459*333d2b36SAndroid Build Coastguard Worker 460*333d2b36SAndroid Build Coastguard Workerfunc (m *regexMatcher) Test(value string) bool { 461*333d2b36SAndroid Build Coastguard Worker return m.re.MatchString(value) 462*333d2b36SAndroid Build Coastguard Worker} 463*333d2b36SAndroid Build Coastguard Worker 464*333d2b36SAndroid Build Coastguard Workerfunc (m *regexMatcher) String() string { 465*333d2b36SAndroid Build Coastguard Worker return ".regexp(" + m.re.String() + ")" 466*333d2b36SAndroid Build Coastguard Worker} 467*333d2b36SAndroid Build Coastguard Worker 468*333d2b36SAndroid Build Coastguard Workertype notInListMatcher struct { 469*333d2b36SAndroid Build Coastguard Worker allowed []string 470*333d2b36SAndroid Build Coastguard Worker} 471*333d2b36SAndroid Build Coastguard Worker 472*333d2b36SAndroid Build Coastguard Workerfunc (m *notInListMatcher) Test(value string) bool { 473*333d2b36SAndroid Build Coastguard Worker return !InList(value, m.allowed) 474*333d2b36SAndroid Build Coastguard Worker} 475*333d2b36SAndroid Build Coastguard Worker 476*333d2b36SAndroid Build Coastguard Workerfunc (m *notInListMatcher) String() string { 477*333d2b36SAndroid Build Coastguard Worker return ".not-in-list(" + strings.Join(m.allowed, ",") + ")" 478*333d2b36SAndroid Build Coastguard Worker} 479*333d2b36SAndroid Build Coastguard Worker 480*333d2b36SAndroid Build Coastguard Workertype isSetMatcher struct{} 481*333d2b36SAndroid Build Coastguard Worker 482*333d2b36SAndroid Build Coastguard Workerfunc (m *isSetMatcher) Test(value string) bool { 483*333d2b36SAndroid Build Coastguard Worker return value != "" 484*333d2b36SAndroid Build Coastguard Worker} 485*333d2b36SAndroid Build Coastguard Worker 486*333d2b36SAndroid Build Coastguard Workerfunc (m *isSetMatcher) String() string { 487*333d2b36SAndroid Build Coastguard Worker return ".is-set" 488*333d2b36SAndroid Build Coastguard Worker} 489*333d2b36SAndroid Build Coastguard Worker 490*333d2b36SAndroid Build Coastguard Workervar isSetMatcherInstance = &isSetMatcher{} 491*333d2b36SAndroid Build Coastguard Worker 492*333d2b36SAndroid Build Coastguard Workertype ruleProperty struct { 493*333d2b36SAndroid Build Coastguard Worker fields []string // e.x.: Vndk.Enabled 494*333d2b36SAndroid Build Coastguard Worker matcher ValueMatcher 495*333d2b36SAndroid Build Coastguard Worker} 496*333d2b36SAndroid Build Coastguard Worker 497*333d2b36SAndroid Build Coastguard Workerfunc (r *ruleProperty) String() string { 498*333d2b36SAndroid Build Coastguard Worker return fmt.Sprintf("%q matches: %s", strings.Join(r.fields, "."), r.matcher) 499*333d2b36SAndroid Build Coastguard Worker} 500*333d2b36SAndroid Build Coastguard Worker 501*333d2b36SAndroid Build Coastguard Workertype ruleProperties []ruleProperty 502*333d2b36SAndroid Build Coastguard Worker 503*333d2b36SAndroid Build Coastguard Workerfunc (r ruleProperties) String() string { 504*333d2b36SAndroid Build Coastguard Worker var s []string 505*333d2b36SAndroid Build Coastguard Worker for _, r := range r { 506*333d2b36SAndroid Build Coastguard Worker s = append(s, r.String()) 507*333d2b36SAndroid Build Coastguard Worker } 508*333d2b36SAndroid Build Coastguard Worker return strings.Join(s, " ") 509*333d2b36SAndroid Build Coastguard Worker} 510*333d2b36SAndroid Build Coastguard Worker 511*333d2b36SAndroid Build Coastguard Worker// A NeverAllow rule. 512*333d2b36SAndroid Build Coastguard Workertype Rule interface { 513*333d2b36SAndroid Build Coastguard Worker In(path ...string) Rule 514*333d2b36SAndroid Build Coastguard Worker 515*333d2b36SAndroid Build Coastguard Worker NotIn(path ...string) Rule 516*333d2b36SAndroid Build Coastguard Worker 517*333d2b36SAndroid Build Coastguard Worker InDirectDeps(deps ...string) Rule 518*333d2b36SAndroid Build Coastguard Worker 519*333d2b36SAndroid Build Coastguard Worker WithOsClass(osClasses ...OsClass) Rule 520*333d2b36SAndroid Build Coastguard Worker 521*333d2b36SAndroid Build Coastguard Worker ModuleType(types ...string) Rule 522*333d2b36SAndroid Build Coastguard Worker 523*333d2b36SAndroid Build Coastguard Worker NotModuleType(types ...string) Rule 524*333d2b36SAndroid Build Coastguard Worker 525*333d2b36SAndroid Build Coastguard Worker With(properties, value string) Rule 526*333d2b36SAndroid Build Coastguard Worker 527*333d2b36SAndroid Build Coastguard Worker WithMatcher(properties string, matcher ValueMatcher) Rule 528*333d2b36SAndroid Build Coastguard Worker 529*333d2b36SAndroid Build Coastguard Worker Without(properties, value string) Rule 530*333d2b36SAndroid Build Coastguard Worker 531*333d2b36SAndroid Build Coastguard Worker WithoutMatcher(properties string, matcher ValueMatcher) Rule 532*333d2b36SAndroid Build Coastguard Worker 533*333d2b36SAndroid Build Coastguard Worker DefinedInBpFile() Rule 534*333d2b36SAndroid Build Coastguard Worker 535*333d2b36SAndroid Build Coastguard Worker Because(reason string) Rule 536*333d2b36SAndroid Build Coastguard Worker} 537*333d2b36SAndroid Build Coastguard Worker 538*333d2b36SAndroid Build Coastguard Workertype rule struct { 539*333d2b36SAndroid Build Coastguard Worker // User string for why this is a thing. 540*333d2b36SAndroid Build Coastguard Worker reason string 541*333d2b36SAndroid Build Coastguard Worker 542*333d2b36SAndroid Build Coastguard Worker paths []string 543*333d2b36SAndroid Build Coastguard Worker unlessPaths []string 544*333d2b36SAndroid Build Coastguard Worker 545*333d2b36SAndroid Build Coastguard Worker directDeps map[string]bool 546*333d2b36SAndroid Build Coastguard Worker 547*333d2b36SAndroid Build Coastguard Worker osClasses []OsClass 548*333d2b36SAndroid Build Coastguard Worker 549*333d2b36SAndroid Build Coastguard Worker moduleTypes []string 550*333d2b36SAndroid Build Coastguard Worker unlessModuleTypes []string 551*333d2b36SAndroid Build Coastguard Worker 552*333d2b36SAndroid Build Coastguard Worker props ruleProperties 553*333d2b36SAndroid Build Coastguard Worker unlessProps ruleProperties 554*333d2b36SAndroid Build Coastguard Worker 555*333d2b36SAndroid Build Coastguard Worker onlyBootclasspathJar bool 556*333d2b36SAndroid Build Coastguard Worker 557*333d2b36SAndroid Build Coastguard Worker definedInBp bool 558*333d2b36SAndroid Build Coastguard Worker} 559*333d2b36SAndroid Build Coastguard Worker 560*333d2b36SAndroid Build Coastguard Worker// Create a new NeverAllow rule. 561*333d2b36SAndroid Build Coastguard Workerfunc NeverAllow() Rule { 562*333d2b36SAndroid Build Coastguard Worker return &rule{directDeps: make(map[string]bool)} 563*333d2b36SAndroid Build Coastguard Worker} 564*333d2b36SAndroid Build Coastguard Worker 565*333d2b36SAndroid Build Coastguard Worker// In adds path(s) where this rule applies. 566*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) In(path ...string) Rule { 567*333d2b36SAndroid Build Coastguard Worker r.paths = append(r.paths, cleanPaths(path)...) 568*333d2b36SAndroid Build Coastguard Worker return r 569*333d2b36SAndroid Build Coastguard Worker} 570*333d2b36SAndroid Build Coastguard Worker 571*333d2b36SAndroid Build Coastguard Worker// NotIn adds path(s) to that this rule does not apply to. 572*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) NotIn(path ...string) Rule { 573*333d2b36SAndroid Build Coastguard Worker r.unlessPaths = append(r.unlessPaths, cleanPaths(path)...) 574*333d2b36SAndroid Build Coastguard Worker return r 575*333d2b36SAndroid Build Coastguard Worker} 576*333d2b36SAndroid Build Coastguard Worker 577*333d2b36SAndroid Build Coastguard Worker// InDirectDeps adds dep(s) that are not allowed with this rule. 578*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) InDirectDeps(deps ...string) Rule { 579*333d2b36SAndroid Build Coastguard Worker for _, d := range deps { 580*333d2b36SAndroid Build Coastguard Worker r.directDeps[d] = true 581*333d2b36SAndroid Build Coastguard Worker } 582*333d2b36SAndroid Build Coastguard Worker return r 583*333d2b36SAndroid Build Coastguard Worker} 584*333d2b36SAndroid Build Coastguard Worker 585*333d2b36SAndroid Build Coastguard Worker// WithOsClass adds osClass(es) that this rule applies to. 586*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) WithOsClass(osClasses ...OsClass) Rule { 587*333d2b36SAndroid Build Coastguard Worker r.osClasses = append(r.osClasses, osClasses...) 588*333d2b36SAndroid Build Coastguard Worker return r 589*333d2b36SAndroid Build Coastguard Worker} 590*333d2b36SAndroid Build Coastguard Worker 591*333d2b36SAndroid Build Coastguard Worker// ModuleType adds type(s) that this rule applies to. 592*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) ModuleType(types ...string) Rule { 593*333d2b36SAndroid Build Coastguard Worker r.moduleTypes = append(r.moduleTypes, types...) 594*333d2b36SAndroid Build Coastguard Worker return r 595*333d2b36SAndroid Build Coastguard Worker} 596*333d2b36SAndroid Build Coastguard Worker 597*333d2b36SAndroid Build Coastguard Worker// NotModuleType adds type(s) that this rule does not apply to.. 598*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) NotModuleType(types ...string) Rule { 599*333d2b36SAndroid Build Coastguard Worker r.unlessModuleTypes = append(r.unlessModuleTypes, types...) 600*333d2b36SAndroid Build Coastguard Worker return r 601*333d2b36SAndroid Build Coastguard Worker} 602*333d2b36SAndroid Build Coastguard Worker 603*333d2b36SAndroid Build Coastguard Worker// With specifies property/value combinations that are restricted for this rule. 604*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) With(properties, value string) Rule { 605*333d2b36SAndroid Build Coastguard Worker return r.WithMatcher(properties, selectMatcher(value)) 606*333d2b36SAndroid Build Coastguard Worker} 607*333d2b36SAndroid Build Coastguard Worker 608*333d2b36SAndroid Build Coastguard Worker// WithMatcher specifies property/matcher combinations that are restricted for this rule. 609*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) WithMatcher(properties string, matcher ValueMatcher) Rule { 610*333d2b36SAndroid Build Coastguard Worker r.props = append(r.props, ruleProperty{ 611*333d2b36SAndroid Build Coastguard Worker fields: fieldNamesForProperties(properties), 612*333d2b36SAndroid Build Coastguard Worker matcher: matcher, 613*333d2b36SAndroid Build Coastguard Worker }) 614*333d2b36SAndroid Build Coastguard Worker return r 615*333d2b36SAndroid Build Coastguard Worker} 616*333d2b36SAndroid Build Coastguard Worker 617*333d2b36SAndroid Build Coastguard Worker// Without specifies property/value combinations that this rule does not apply to. 618*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) Without(properties, value string) Rule { 619*333d2b36SAndroid Build Coastguard Worker return r.WithoutMatcher(properties, selectMatcher(value)) 620*333d2b36SAndroid Build Coastguard Worker} 621*333d2b36SAndroid Build Coastguard Worker 622*333d2b36SAndroid Build Coastguard Worker// Without specifies property/matcher combinations that this rule does not apply to. 623*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) WithoutMatcher(properties string, matcher ValueMatcher) Rule { 624*333d2b36SAndroid Build Coastguard Worker r.unlessProps = append(r.unlessProps, ruleProperty{ 625*333d2b36SAndroid Build Coastguard Worker fields: fieldNamesForProperties(properties), 626*333d2b36SAndroid Build Coastguard Worker matcher: matcher, 627*333d2b36SAndroid Build Coastguard Worker }) 628*333d2b36SAndroid Build Coastguard Worker return r 629*333d2b36SAndroid Build Coastguard Worker} 630*333d2b36SAndroid Build Coastguard Worker 631*333d2b36SAndroid Build Coastguard Worker// DefinedInBpFile specifies that this rule applies to modules that are defined 632*333d2b36SAndroid Build Coastguard Worker// in bp files, and does not apply to modules that are auto generated by other modules. 633*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) DefinedInBpFile() Rule { 634*333d2b36SAndroid Build Coastguard Worker r.definedInBp = true 635*333d2b36SAndroid Build Coastguard Worker return r 636*333d2b36SAndroid Build Coastguard Worker} 637*333d2b36SAndroid Build Coastguard Worker 638*333d2b36SAndroid Build Coastguard Workerfunc selectMatcher(expected string) ValueMatcher { 639*333d2b36SAndroid Build Coastguard Worker if expected == "*" { 640*333d2b36SAndroid Build Coastguard Worker return anyMatcherInstance 641*333d2b36SAndroid Build Coastguard Worker } 642*333d2b36SAndroid Build Coastguard Worker return &equalMatcher{expected: expected} 643*333d2b36SAndroid Build Coastguard Worker} 644*333d2b36SAndroid Build Coastguard Worker 645*333d2b36SAndroid Build Coastguard Worker// Because specifies a reason for this rule. 646*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) Because(reason string) Rule { 647*333d2b36SAndroid Build Coastguard Worker r.reason = reason 648*333d2b36SAndroid Build Coastguard Worker return r 649*333d2b36SAndroid Build Coastguard Worker} 650*333d2b36SAndroid Build Coastguard Worker 651*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) String() string { 652*333d2b36SAndroid Build Coastguard Worker s := []string{"neverallow requirements. Not allowed:"} 653*333d2b36SAndroid Build Coastguard Worker if len(r.paths) > 0 { 654*333d2b36SAndroid Build Coastguard Worker s = append(s, fmt.Sprintf("in dirs: %q", r.paths)) 655*333d2b36SAndroid Build Coastguard Worker } 656*333d2b36SAndroid Build Coastguard Worker if len(r.moduleTypes) > 0 { 657*333d2b36SAndroid Build Coastguard Worker s = append(s, fmt.Sprintf("module types: %q", r.moduleTypes)) 658*333d2b36SAndroid Build Coastguard Worker } 659*333d2b36SAndroid Build Coastguard Worker if len(r.props) > 0 { 660*333d2b36SAndroid Build Coastguard Worker s = append(s, fmt.Sprintf("properties matching: %s", r.props)) 661*333d2b36SAndroid Build Coastguard Worker } 662*333d2b36SAndroid Build Coastguard Worker if len(r.directDeps) > 0 { 663*333d2b36SAndroid Build Coastguard Worker s = append(s, fmt.Sprintf("dep(s): %q", SortedKeys(r.directDeps))) 664*333d2b36SAndroid Build Coastguard Worker } 665*333d2b36SAndroid Build Coastguard Worker if len(r.osClasses) > 0 { 666*333d2b36SAndroid Build Coastguard Worker s = append(s, fmt.Sprintf("os class(es): %q", r.osClasses)) 667*333d2b36SAndroid Build Coastguard Worker } 668*333d2b36SAndroid Build Coastguard Worker if len(r.unlessPaths) > 0 { 669*333d2b36SAndroid Build Coastguard Worker s = append(s, fmt.Sprintf("EXCEPT in dirs: %q", r.unlessPaths)) 670*333d2b36SAndroid Build Coastguard Worker } 671*333d2b36SAndroid Build Coastguard Worker if len(r.unlessModuleTypes) > 0 { 672*333d2b36SAndroid Build Coastguard Worker s = append(s, fmt.Sprintf("EXCEPT module types: %q", r.unlessModuleTypes)) 673*333d2b36SAndroid Build Coastguard Worker } 674*333d2b36SAndroid Build Coastguard Worker if len(r.unlessProps) > 0 { 675*333d2b36SAndroid Build Coastguard Worker s = append(s, fmt.Sprintf("EXCEPT properties matching: %q", r.unlessProps)) 676*333d2b36SAndroid Build Coastguard Worker } 677*333d2b36SAndroid Build Coastguard Worker if len(r.reason) != 0 { 678*333d2b36SAndroid Build Coastguard Worker s = append(s, " which is restricted because "+r.reason) 679*333d2b36SAndroid Build Coastguard Worker } 680*333d2b36SAndroid Build Coastguard Worker if len(s) == 1 { 681*333d2b36SAndroid Build Coastguard Worker s[0] = "neverallow requirements (empty)" 682*333d2b36SAndroid Build Coastguard Worker } 683*333d2b36SAndroid Build Coastguard Worker return strings.Join(s, "\n\t") 684*333d2b36SAndroid Build Coastguard Worker} 685*333d2b36SAndroid Build Coastguard Worker 686*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) appliesToPath(dir string) bool { 687*333d2b36SAndroid Build Coastguard Worker includePath := len(r.paths) == 0 || HasAnyPrefix(dir, r.paths) 688*333d2b36SAndroid Build Coastguard Worker excludePath := HasAnyPrefix(dir, r.unlessPaths) 689*333d2b36SAndroid Build Coastguard Worker return includePath && !excludePath 690*333d2b36SAndroid Build Coastguard Worker} 691*333d2b36SAndroid Build Coastguard Worker 692*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) appliesToDirectDeps(ctx BottomUpMutatorContext) bool { 693*333d2b36SAndroid Build Coastguard Worker if len(r.directDeps) == 0 { 694*333d2b36SAndroid Build Coastguard Worker return true 695*333d2b36SAndroid Build Coastguard Worker } 696*333d2b36SAndroid Build Coastguard Worker 697*333d2b36SAndroid Build Coastguard Worker matches := false 698*333d2b36SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(m Module) { 699*333d2b36SAndroid Build Coastguard Worker if !matches { 700*333d2b36SAndroid Build Coastguard Worker name := ctx.OtherModuleName(m) 701*333d2b36SAndroid Build Coastguard Worker matches = r.directDeps[name] 702*333d2b36SAndroid Build Coastguard Worker } 703*333d2b36SAndroid Build Coastguard Worker }) 704*333d2b36SAndroid Build Coastguard Worker 705*333d2b36SAndroid Build Coastguard Worker return matches 706*333d2b36SAndroid Build Coastguard Worker} 707*333d2b36SAndroid Build Coastguard Worker 708*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) appliesToOsClass(osClass OsClass) bool { 709*333d2b36SAndroid Build Coastguard Worker if len(r.osClasses) == 0 { 710*333d2b36SAndroid Build Coastguard Worker return true 711*333d2b36SAndroid Build Coastguard Worker } 712*333d2b36SAndroid Build Coastguard Worker 713*333d2b36SAndroid Build Coastguard Worker for _, c := range r.osClasses { 714*333d2b36SAndroid Build Coastguard Worker if c == osClass { 715*333d2b36SAndroid Build Coastguard Worker return true 716*333d2b36SAndroid Build Coastguard Worker } 717*333d2b36SAndroid Build Coastguard Worker } 718*333d2b36SAndroid Build Coastguard Worker 719*333d2b36SAndroid Build Coastguard Worker return false 720*333d2b36SAndroid Build Coastguard Worker} 721*333d2b36SAndroid Build Coastguard Worker 722*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) appliesToModuleType(moduleType string) bool { 723*333d2b36SAndroid Build Coastguard Worker // Remove prefix for auto-generated modules 724*333d2b36SAndroid Build Coastguard Worker moduleType = strings.TrimSuffix(moduleType, "__loadHookModule") 725*333d2b36SAndroid Build Coastguard Worker moduleType = strings.TrimSuffix(moduleType, "__bottomUpMutatorModule") 726*333d2b36SAndroid Build Coastguard Worker return (len(r.moduleTypes) == 0 || InList(moduleType, r.moduleTypes)) && !InList(moduleType, r.unlessModuleTypes) 727*333d2b36SAndroid Build Coastguard Worker} 728*333d2b36SAndroid Build Coastguard Worker 729*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) appliesToProperties(ctx BottomUpMutatorContext, properties []interface{}) bool { 730*333d2b36SAndroid Build Coastguard Worker includeProps := hasAllProperties(ctx, properties, r.props) 731*333d2b36SAndroid Build Coastguard Worker excludeProps := hasAnyProperty(ctx, properties, r.unlessProps) 732*333d2b36SAndroid Build Coastguard Worker return includeProps && !excludeProps 733*333d2b36SAndroid Build Coastguard Worker} 734*333d2b36SAndroid Build Coastguard Worker 735*333d2b36SAndroid Build Coastguard Workerfunc (r *rule) appliesToBpDefinedModule(ctx BottomUpMutatorContext) bool { 736*333d2b36SAndroid Build Coastguard Worker if !r.definedInBp { 737*333d2b36SAndroid Build Coastguard Worker return true 738*333d2b36SAndroid Build Coastguard Worker } 739*333d2b36SAndroid Build Coastguard Worker return !ctx.OtherModuleIsAutoGenerated(ctx.Module()) == r.definedInBp 740*333d2b36SAndroid Build Coastguard Worker} 741*333d2b36SAndroid Build Coastguard Worker 742*333d2b36SAndroid Build Coastguard Workerfunc StartsWith(prefix string) ValueMatcher { 743*333d2b36SAndroid Build Coastguard Worker return &startsWithMatcher{prefix} 744*333d2b36SAndroid Build Coastguard Worker} 745*333d2b36SAndroid Build Coastguard Worker 746*333d2b36SAndroid Build Coastguard Workerfunc Regexp(re string) ValueMatcher { 747*333d2b36SAndroid Build Coastguard Worker r, err := regexp.Compile(re) 748*333d2b36SAndroid Build Coastguard Worker if err != nil { 749*333d2b36SAndroid Build Coastguard Worker panic(err) 750*333d2b36SAndroid Build Coastguard Worker } 751*333d2b36SAndroid Build Coastguard Worker return ®exMatcher{r} 752*333d2b36SAndroid Build Coastguard Worker} 753*333d2b36SAndroid Build Coastguard Worker 754*333d2b36SAndroid Build Coastguard Workerfunc NotInList(allowed []string) ValueMatcher { 755*333d2b36SAndroid Build Coastguard Worker return ¬InListMatcher{allowed} 756*333d2b36SAndroid Build Coastguard Worker} 757*333d2b36SAndroid Build Coastguard Worker 758*333d2b36SAndroid Build Coastguard Worker// assorted utils 759*333d2b36SAndroid Build Coastguard Worker 760*333d2b36SAndroid Build Coastguard Workerfunc cleanPaths(paths []string) []string { 761*333d2b36SAndroid Build Coastguard Worker res := make([]string, len(paths)) 762*333d2b36SAndroid Build Coastguard Worker for i, v := range paths { 763*333d2b36SAndroid Build Coastguard Worker res[i] = filepath.Clean(v) + "/" 764*333d2b36SAndroid Build Coastguard Worker } 765*333d2b36SAndroid Build Coastguard Worker return res 766*333d2b36SAndroid Build Coastguard Worker} 767*333d2b36SAndroid Build Coastguard Worker 768*333d2b36SAndroid Build Coastguard Workerfunc fieldNamesForProperties(propertyNames string) []string { 769*333d2b36SAndroid Build Coastguard Worker names := strings.Split(propertyNames, ".") 770*333d2b36SAndroid Build Coastguard Worker for i, v := range names { 771*333d2b36SAndroid Build Coastguard Worker names[i] = proptools.FieldNameForProperty(v) 772*333d2b36SAndroid Build Coastguard Worker } 773*333d2b36SAndroid Build Coastguard Worker return names 774*333d2b36SAndroid Build Coastguard Worker} 775*333d2b36SAndroid Build Coastguard Worker 776*333d2b36SAndroid Build Coastguard Workerfunc hasAnyProperty(ctx BottomUpMutatorContext, properties []interface{}, props []ruleProperty) bool { 777*333d2b36SAndroid Build Coastguard Worker for _, v := range props { 778*333d2b36SAndroid Build Coastguard Worker if hasProperty(ctx, properties, v) { 779*333d2b36SAndroid Build Coastguard Worker return true 780*333d2b36SAndroid Build Coastguard Worker } 781*333d2b36SAndroid Build Coastguard Worker } 782*333d2b36SAndroid Build Coastguard Worker return false 783*333d2b36SAndroid Build Coastguard Worker} 784*333d2b36SAndroid Build Coastguard Worker 785*333d2b36SAndroid Build Coastguard Workerfunc hasAllProperties(ctx BottomUpMutatorContext, properties []interface{}, props []ruleProperty) bool { 786*333d2b36SAndroid Build Coastguard Worker for _, v := range props { 787*333d2b36SAndroid Build Coastguard Worker if !hasProperty(ctx, properties, v) { 788*333d2b36SAndroid Build Coastguard Worker return false 789*333d2b36SAndroid Build Coastguard Worker } 790*333d2b36SAndroid Build Coastguard Worker } 791*333d2b36SAndroid Build Coastguard Worker return true 792*333d2b36SAndroid Build Coastguard Worker} 793*333d2b36SAndroid Build Coastguard Worker 794*333d2b36SAndroid Build Coastguard Workerfunc hasProperty(ctx BottomUpMutatorContext, properties []interface{}, prop ruleProperty) bool { 795*333d2b36SAndroid Build Coastguard Worker for _, propertyStruct := range properties { 796*333d2b36SAndroid Build Coastguard Worker propertiesValue := reflect.ValueOf(propertyStruct).Elem() 797*333d2b36SAndroid Build Coastguard Worker for _, v := range prop.fields { 798*333d2b36SAndroid Build Coastguard Worker if !propertiesValue.IsValid() { 799*333d2b36SAndroid Build Coastguard Worker break 800*333d2b36SAndroid Build Coastguard Worker } 801*333d2b36SAndroid Build Coastguard Worker propertiesValue = propertiesValue.FieldByName(v) 802*333d2b36SAndroid Build Coastguard Worker } 803*333d2b36SAndroid Build Coastguard Worker if !propertiesValue.IsValid() { 804*333d2b36SAndroid Build Coastguard Worker continue 805*333d2b36SAndroid Build Coastguard Worker } 806*333d2b36SAndroid Build Coastguard Worker 807*333d2b36SAndroid Build Coastguard Worker check := func(value string) bool { 808*333d2b36SAndroid Build Coastguard Worker return prop.matcher.Test(value) 809*333d2b36SAndroid Build Coastguard Worker } 810*333d2b36SAndroid Build Coastguard Worker 811*333d2b36SAndroid Build Coastguard Worker if matchValue(ctx, propertiesValue, check) { 812*333d2b36SAndroid Build Coastguard Worker return true 813*333d2b36SAndroid Build Coastguard Worker } 814*333d2b36SAndroid Build Coastguard Worker } 815*333d2b36SAndroid Build Coastguard Worker return false 816*333d2b36SAndroid Build Coastguard Worker} 817*333d2b36SAndroid Build Coastguard Worker 818*333d2b36SAndroid Build Coastguard Workerfunc matchValue(ctx BottomUpMutatorContext, value reflect.Value, check func(string) bool) bool { 819*333d2b36SAndroid Build Coastguard Worker if !value.IsValid() { 820*333d2b36SAndroid Build Coastguard Worker return false 821*333d2b36SAndroid Build Coastguard Worker } 822*333d2b36SAndroid Build Coastguard Worker 823*333d2b36SAndroid Build Coastguard Worker if value.Kind() == reflect.Ptr { 824*333d2b36SAndroid Build Coastguard Worker if value.IsNil() { 825*333d2b36SAndroid Build Coastguard Worker return check("") 826*333d2b36SAndroid Build Coastguard Worker } 827*333d2b36SAndroid Build Coastguard Worker value = value.Elem() 828*333d2b36SAndroid Build Coastguard Worker } 829*333d2b36SAndroid Build Coastguard Worker 830*333d2b36SAndroid Build Coastguard Worker switch v := value.Interface().(type) { 831*333d2b36SAndroid Build Coastguard Worker case string: 832*333d2b36SAndroid Build Coastguard Worker return check(v) 833*333d2b36SAndroid Build Coastguard Worker case bool: 834*333d2b36SAndroid Build Coastguard Worker return check(strconv.FormatBool(v)) 835*333d2b36SAndroid Build Coastguard Worker case int: 836*333d2b36SAndroid Build Coastguard Worker return check(strconv.FormatInt((int64)(v), 10)) 837*333d2b36SAndroid Build Coastguard Worker case []string: 838*333d2b36SAndroid Build Coastguard Worker for _, v := range v { 839*333d2b36SAndroid Build Coastguard Worker if check(v) { 840*333d2b36SAndroid Build Coastguard Worker return true 841*333d2b36SAndroid Build Coastguard Worker } 842*333d2b36SAndroid Build Coastguard Worker } 843*333d2b36SAndroid Build Coastguard Worker return false 844*333d2b36SAndroid Build Coastguard Worker case proptools.Configurable[string]: 845*333d2b36SAndroid Build Coastguard Worker return check(v.GetOrDefault(ctx, "")) 846*333d2b36SAndroid Build Coastguard Worker case proptools.Configurable[bool]: 847*333d2b36SAndroid Build Coastguard Worker return check(strconv.FormatBool(v.GetOrDefault(ctx, false))) 848*333d2b36SAndroid Build Coastguard Worker case proptools.Configurable[[]string]: 849*333d2b36SAndroid Build Coastguard Worker for _, v := range v.GetOrDefault(ctx, nil) { 850*333d2b36SAndroid Build Coastguard Worker if check(v) { 851*333d2b36SAndroid Build Coastguard Worker return true 852*333d2b36SAndroid Build Coastguard Worker } 853*333d2b36SAndroid Build Coastguard Worker } 854*333d2b36SAndroid Build Coastguard Worker return false 855*333d2b36SAndroid Build Coastguard Worker } 856*333d2b36SAndroid Build Coastguard Worker 857*333d2b36SAndroid Build Coastguard Worker panic("Can't handle type: " + value.Kind().String()) 858*333d2b36SAndroid Build Coastguard Worker} 859*333d2b36SAndroid Build Coastguard Worker 860*333d2b36SAndroid Build Coastguard Workervar neverallowRulesKey = NewOnceKey("neverallowRules") 861*333d2b36SAndroid Build Coastguard Worker 862*333d2b36SAndroid Build Coastguard Workerfunc neverallowRules(config Config) []Rule { 863*333d2b36SAndroid Build Coastguard Worker return config.Once(neverallowRulesKey, func() interface{} { 864*333d2b36SAndroid Build Coastguard Worker // No test rules were set by setTestNeverallowRules, use the global rules 865*333d2b36SAndroid Build Coastguard Worker return neverallows 866*333d2b36SAndroid Build Coastguard Worker }).([]Rule) 867*333d2b36SAndroid Build Coastguard Worker} 868*333d2b36SAndroid Build Coastguard Worker 869*333d2b36SAndroid Build Coastguard Worker// Overrides the default neverallow rules for the supplied config. 870*333d2b36SAndroid Build Coastguard Worker// 871*333d2b36SAndroid Build Coastguard Worker// For testing only. 872*333d2b36SAndroid Build Coastguard Workerfunc setTestNeverallowRules(config Config, testRules []Rule) { 873*333d2b36SAndroid Build Coastguard Worker config.Once(neverallowRulesKey, func() interface{} { return testRules }) 874*333d2b36SAndroid Build Coastguard Worker} 875*333d2b36SAndroid Build Coastguard Worker 876*333d2b36SAndroid Build Coastguard Worker// Prepares for a test by setting neverallow rules and enabling the mutator. 877*333d2b36SAndroid Build Coastguard Worker// 878*333d2b36SAndroid Build Coastguard Worker// If the supplied rules are nil then the default rules are used. 879*333d2b36SAndroid Build Coastguard Workerfunc PrepareForTestWithNeverallowRules(testRules []Rule) FixturePreparer { 880*333d2b36SAndroid Build Coastguard Worker return GroupFixturePreparers( 881*333d2b36SAndroid Build Coastguard Worker FixtureModifyConfig(func(config Config) { 882*333d2b36SAndroid Build Coastguard Worker if testRules != nil { 883*333d2b36SAndroid Build Coastguard Worker setTestNeverallowRules(config, testRules) 884*333d2b36SAndroid Build Coastguard Worker } 885*333d2b36SAndroid Build Coastguard Worker }), 886*333d2b36SAndroid Build Coastguard Worker FixtureRegisterWithContext(func(ctx RegistrationContext) { 887*333d2b36SAndroid Build Coastguard Worker ctx.PostDepsMutators(registerNeverallowMutator) 888*333d2b36SAndroid Build Coastguard Worker }), 889*333d2b36SAndroid Build Coastguard Worker ) 890*333d2b36SAndroid Build Coastguard Worker} 891