1// Copyright 2022 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package android 16 17import ( 18 "encoding/json" 19 "os" 20 "strings" 21 22 "github.com/google/blueprint" 23) 24 25func init() { 26 RegisterPluginSingletonBuildComponents(InitRegistrationContext) 27} 28 29func RegisterPluginSingletonBuildComponents(ctx RegistrationContext) { 30 ctx.RegisterParallelSingletonType("plugins", pluginSingletonFactory) 31} 32 33// pluginSingleton is a singleton to handle allowlisting of the final Android-<product_name>.mk file 34// output. 35func pluginSingletonFactory() Singleton { 36 return &pluginSingleton{} 37} 38 39type pluginSingleton struct{} 40 41var allowedPluginsByName = map[string]bool{ 42 "aidl-soong-rules": true, 43 "arm_compute_library_nn_driver": true, 44 "cuttlefish-soong-rules": true, 45 "gki-soong-rules": true, 46 "hidl-soong-rules": true, 47 "kernel-config-soong-rules": true, 48 "soong-angle-codegen": true, 49 "soong-api": true, 50 "soong-art": true, 51 "soong-ca-certificates": true, 52 "soong-ca-certificates-apex": true, 53 "soong-clang": true, 54 "soong-clang-prebuilts": true, 55 "soong-csuite": true, 56 "soong-fluoride": true, 57 "soong-fs_config": true, 58 "soong-icu": true, 59 "soong-java-config-error_prone": true, 60 "soong-libchrome": true, 61 "soong-llvm": true, 62 "soong-robolectric": true, 63 "soong-rust-prebuilts": true, 64 "soong-selinux": true, 65 "soong-wayland-protocol-codegen": true, 66 "treble_report_app": true, 67 "treble_report_local": true, 68 "treble_report_module": true, 69 "vintf-compatibility-matrix-soong-rules": true, 70 "xsdc-soong-rules": true, 71} 72 73var internalPluginsPaths = []string{ 74 "vendor/google/build/soong/internal_plugins.json", 75} 76 77type pluginProvider interface { 78 IsPluginFor(string) bool 79} 80 81func maybeAddInternalPluginsToAllowlist(ctx SingletonContext) { 82 for _, internalPluginsPath := range internalPluginsPaths { 83 if path := ExistentPathForSource(ctx, internalPluginsPath); path.Valid() { 84 ctx.AddNinjaFileDeps(path.String()) 85 absPath := absolutePath(path.String()) 86 var moreAllowed map[string]bool 87 data, err := os.ReadFile(absPath) 88 if err != nil { 89 ctx.Errorf("Failed to open internal plugins path %q %q", internalPluginsPath, err) 90 } 91 if err := json.Unmarshal(data, &moreAllowed); err != nil { 92 ctx.Errorf("Internal plugins file %q did not parse correctly: %q", data, err) 93 } 94 for k, v := range moreAllowed { 95 allowedPluginsByName[k] = v 96 } 97 } 98 } 99} 100 101func (p *pluginSingleton) GenerateBuildActions(ctx SingletonContext) { 102 for _, p := range ctx.DeviceConfig().BuildBrokenPluginValidation() { 103 allowedPluginsByName[p] = true 104 } 105 maybeAddInternalPluginsToAllowlist(ctx) 106 107 disallowedPlugins := map[string]bool{} 108 ctx.VisitAllModulesBlueprint(func(module blueprint.Module) { 109 if ctx.ModuleType(module) != "bootstrap_go_package" { 110 return 111 } 112 113 p, ok := module.(pluginProvider) 114 if !ok || !p.IsPluginFor("soong_build") { 115 return 116 } 117 118 name := ctx.ModuleName(module) 119 if _, ok := allowedPluginsByName[name]; ok { 120 return 121 } 122 123 dir := ctx.ModuleDir(module) 124 125 // allow use of plugins within Soong to not allowlist everything 126 if strings.HasPrefix(dir, "build/soong") { 127 return 128 } 129 130 // allow third party users outside of external to create new plugins, i.e. non-google paths 131 // under vendor or hardware 132 if !strings.HasPrefix(dir, "external/") && IsThirdPartyPath(dir) { 133 return 134 } 135 disallowedPlugins[name] = true 136 }) 137 if len(disallowedPlugins) > 0 { 138 ctx.Errorf("New plugins are not supported; however %q were found. Please reach out to the build team or use BUILD_BROKEN_PLUGIN_VALIDATION (see Changes.md for more info).", SortedStringKeys(disallowedPlugins)) 139 } 140} 141