1*e4a36f41SAndroid Build Coastguard Worker// Copyright (C) 2023 The Android Open Source Project 2*e4a36f41SAndroid Build Coastguard Worker// 3*e4a36f41SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*e4a36f41SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*e4a36f41SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*e4a36f41SAndroid Build Coastguard Worker// 7*e4a36f41SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*e4a36f41SAndroid Build Coastguard Worker// 9*e4a36f41SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*e4a36f41SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*e4a36f41SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*e4a36f41SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*e4a36f41SAndroid Build Coastguard Worker// limitations under the License. 14*e4a36f41SAndroid Build Coastguard Worker 15*e4a36f41SAndroid Build Coastguard Workerpackage selinux 16*e4a36f41SAndroid Build Coastguard Worker 17*e4a36f41SAndroid Build Coastguard Workerimport ( 18*e4a36f41SAndroid Build Coastguard Worker "maps" 19*e4a36f41SAndroid Build Coastguard Worker 20*e4a36f41SAndroid Build Coastguard Worker "android/soong/android" 21*e4a36f41SAndroid Build Coastguard Worker 22*e4a36f41SAndroid Build Coastguard Worker "github.com/google/blueprint" 23*e4a36f41SAndroid Build Coastguard Worker) 24*e4a36f41SAndroid Build Coastguard Worker 25*e4a36f41SAndroid Build Coastguard Workervar ( 26*e4a36f41SAndroid Build Coastguard Worker flagsDepTag = dependencyTag{name: "flags"} 27*e4a36f41SAndroid Build Coastguard Worker buildFlagsDepTag = dependencyTag{name: "build_flags"} 28*e4a36f41SAndroid Build Coastguard Worker) 29*e4a36f41SAndroid Build Coastguard Worker 30*e4a36f41SAndroid Build Coastguard Workerfunc init() { 31*e4a36f41SAndroid Build Coastguard Worker ctx := android.InitRegistrationContext 32*e4a36f41SAndroid Build Coastguard Worker ctx.RegisterModuleType("se_flags", flagsFactory) 33*e4a36f41SAndroid Build Coastguard Worker ctx.RegisterModuleType("se_flags_collector", flagsCollectorFactory) 34*e4a36f41SAndroid Build Coastguard Worker} 35*e4a36f41SAndroid Build Coastguard Worker 36*e4a36f41SAndroid Build Coastguard Workertype flagsProperties struct { 37*e4a36f41SAndroid Build Coastguard Worker // List of build time flags for flag-guarding. 38*e4a36f41SAndroid Build Coastguard Worker Flags []string 39*e4a36f41SAndroid Build Coastguard Worker 40*e4a36f41SAndroid Build Coastguard Worker // List of se_flags_collector modules to export flags to. 41*e4a36f41SAndroid Build Coastguard Worker Export_to []string 42*e4a36f41SAndroid Build Coastguard Worker} 43*e4a36f41SAndroid Build Coastguard Worker 44*e4a36f41SAndroid Build Coastguard Workertype flagsModule struct { 45*e4a36f41SAndroid Build Coastguard Worker android.ModuleBase 46*e4a36f41SAndroid Build Coastguard Worker properties flagsProperties 47*e4a36f41SAndroid Build Coastguard Worker} 48*e4a36f41SAndroid Build Coastguard Worker 49*e4a36f41SAndroid Build Coastguard Workertype flagsInfo struct { 50*e4a36f41SAndroid Build Coastguard Worker Flags []string 51*e4a36f41SAndroid Build Coastguard Worker} 52*e4a36f41SAndroid Build Coastguard Worker 53*e4a36f41SAndroid Build Coastguard Workervar flagsProviderKey = blueprint.NewProvider[flagsInfo]() 54*e4a36f41SAndroid Build Coastguard Worker 55*e4a36f41SAndroid Build Coastguard Worker// se_flags contains a list of build time flags for sepolicy. Build time flags are defined under 56*e4a36f41SAndroid Build Coastguard Worker// .scl files (e.g. build/release/build_flags.scl). By importing flags with se_flags modules, 57*e4a36f41SAndroid Build Coastguard Worker// sepolicy rules can be guarded by `is_flag_enabled` / `is_flag_disabled` macro. 58*e4a36f41SAndroid Build Coastguard Worker// 59*e4a36f41SAndroid Build Coastguard Worker// For example, an Android.bp file could have: 60*e4a36f41SAndroid Build Coastguard Worker// 61*e4a36f41SAndroid Build Coastguard Worker// se_flags { 62*e4a36f41SAndroid Build Coastguard Worker// name: "aosp_selinux_flags", 63*e4a36f41SAndroid Build Coastguard Worker// flags: ["RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT"], 64*e4a36f41SAndroid Build Coastguard Worker// export_to: ["all_selinux_flags"], 65*e4a36f41SAndroid Build Coastguard Worker// } 66*e4a36f41SAndroid Build Coastguard Worker// 67*e4a36f41SAndroid Build Coastguard Worker// And then one could flag-guard .te file rules: 68*e4a36f41SAndroid Build Coastguard Worker// 69*e4a36f41SAndroid Build Coastguard Worker// is_flag_enabled(RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT, ` 70*e4a36f41SAndroid Build Coastguard Worker// type vfio_handler, domain, coredomain; 71*e4a36f41SAndroid Build Coastguard Worker// binder_use(vfio_handler) 72*e4a36f41SAndroid Build Coastguard Worker// ') 73*e4a36f41SAndroid Build Coastguard Worker// 74*e4a36f41SAndroid Build Coastguard Worker// or contexts entries: 75*e4a36f41SAndroid Build Coastguard Worker// 76*e4a36f41SAndroid Build Coastguard Worker// is_flag_enabled(RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT, ` 77*e4a36f41SAndroid Build Coastguard Worker// android.system.virtualizationservice_internal.IVfioHandler u:object_r:vfio_handler_service:s0 78*e4a36f41SAndroid Build Coastguard Worker// ') 79*e4a36f41SAndroid Build Coastguard Workerfunc flagsFactory() android.Module { 80*e4a36f41SAndroid Build Coastguard Worker module := &flagsModule{} 81*e4a36f41SAndroid Build Coastguard Worker module.AddProperties(&module.properties) 82*e4a36f41SAndroid Build Coastguard Worker android.InitAndroidModule(module) 83*e4a36f41SAndroid Build Coastguard Worker return module 84*e4a36f41SAndroid Build Coastguard Worker} 85*e4a36f41SAndroid Build Coastguard Worker 86*e4a36f41SAndroid Build Coastguard Workerfunc (f *flagsModule) DepsMutator(ctx android.BottomUpMutatorContext) { 87*e4a36f41SAndroid Build Coastguard Worker // dep se_flag_collector -> se_flags 88*e4a36f41SAndroid Build Coastguard Worker for _, export := range f.properties.Export_to { 89*e4a36f41SAndroid Build Coastguard Worker ctx.AddReverseDependency(ctx.Module(), flagsDepTag, export) 90*e4a36f41SAndroid Build Coastguard Worker } 91*e4a36f41SAndroid Build Coastguard Worker} 92*e4a36f41SAndroid Build Coastguard Worker 93*e4a36f41SAndroid Build Coastguard Workerfunc (f *flagsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 94*e4a36f41SAndroid Build Coastguard Worker android.SetProvider(ctx, flagsProviderKey, flagsInfo{ 95*e4a36f41SAndroid Build Coastguard Worker Flags: f.properties.Flags, 96*e4a36f41SAndroid Build Coastguard Worker }) 97*e4a36f41SAndroid Build Coastguard Worker} 98*e4a36f41SAndroid Build Coastguard Worker 99*e4a36f41SAndroid Build Coastguard Workertype buildFlagsInfo struct { 100*e4a36f41SAndroid Build Coastguard Worker BuildFlags map[string]string 101*e4a36f41SAndroid Build Coastguard Worker} 102*e4a36f41SAndroid Build Coastguard Worker 103*e4a36f41SAndroid Build Coastguard Workervar buildFlagsProviderKey = blueprint.NewProvider[buildFlagsInfo]() 104*e4a36f41SAndroid Build Coastguard Worker 105*e4a36f41SAndroid Build Coastguard Workertype flagsCollectorModule struct { 106*e4a36f41SAndroid Build Coastguard Worker android.ModuleBase 107*e4a36f41SAndroid Build Coastguard Worker buildFlags map[string]string 108*e4a36f41SAndroid Build Coastguard Worker} 109*e4a36f41SAndroid Build Coastguard Worker 110*e4a36f41SAndroid Build Coastguard Worker// se_flags_collector module collects flags from exported se_flags modules (see export_to property 111*e4a36f41SAndroid Build Coastguard Worker// of se_flags modules), and then converts them into build-time flags. It will be used to generate 112*e4a36f41SAndroid Build Coastguard Worker// M4 macros to flag-guard sepolicy. 113*e4a36f41SAndroid Build Coastguard Workerfunc flagsCollectorFactory() android.Module { 114*e4a36f41SAndroid Build Coastguard Worker module := &flagsCollectorModule{} 115*e4a36f41SAndroid Build Coastguard Worker android.InitAndroidModule(module) 116*e4a36f41SAndroid Build Coastguard Worker return module 117*e4a36f41SAndroid Build Coastguard Worker} 118*e4a36f41SAndroid Build Coastguard Worker 119*e4a36f41SAndroid Build Coastguard Workerfunc (f *flagsCollectorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 120*e4a36f41SAndroid Build Coastguard Worker var flags []string 121*e4a36f41SAndroid Build Coastguard Worker ctx.VisitDirectDepsWithTag(flagsDepTag, func(m android.Module) { 122*e4a36f41SAndroid Build Coastguard Worker if dep, ok := android.OtherModuleProvider(ctx, m, flagsProviderKey); ok { 123*e4a36f41SAndroid Build Coastguard Worker flags = append(flags, dep.Flags...) 124*e4a36f41SAndroid Build Coastguard Worker } else { 125*e4a36f41SAndroid Build Coastguard Worker ctx.ModuleErrorf("unknown dependency %q", ctx.OtherModuleName(m)) 126*e4a36f41SAndroid Build Coastguard Worker } 127*e4a36f41SAndroid Build Coastguard Worker }) 128*e4a36f41SAndroid Build Coastguard Worker buildFlags := make(map[string]string) 129*e4a36f41SAndroid Build Coastguard Worker for _, flag := range android.SortedUniqueStrings(flags) { 130*e4a36f41SAndroid Build Coastguard Worker if val, ok := ctx.Config().GetBuildFlag(flag); ok { 131*e4a36f41SAndroid Build Coastguard Worker buildFlags[flag] = val 132*e4a36f41SAndroid Build Coastguard Worker } 133*e4a36f41SAndroid Build Coastguard Worker } 134*e4a36f41SAndroid Build Coastguard Worker android.SetProvider(ctx, buildFlagsProviderKey, buildFlagsInfo{ 135*e4a36f41SAndroid Build Coastguard Worker BuildFlags: buildFlags, 136*e4a36f41SAndroid Build Coastguard Worker }) 137*e4a36f41SAndroid Build Coastguard Worker} 138*e4a36f41SAndroid Build Coastguard Worker 139*e4a36f41SAndroid Build Coastguard Workertype flaggableModuleProperties struct { 140*e4a36f41SAndroid Build Coastguard Worker // List of se_flag_collector modules to be passed to M4 macro. 141*e4a36f41SAndroid Build Coastguard Worker Build_flags []string 142*e4a36f41SAndroid Build Coastguard Worker} 143*e4a36f41SAndroid Build Coastguard Worker 144*e4a36f41SAndroid Build Coastguard Workertype flaggableModule interface { 145*e4a36f41SAndroid Build Coastguard Worker android.Module 146*e4a36f41SAndroid Build Coastguard Worker flagModuleBase() *flaggableModuleBase 147*e4a36f41SAndroid Build Coastguard Worker flagDeps(ctx android.BottomUpMutatorContext) 148*e4a36f41SAndroid Build Coastguard Worker getBuildFlags(ctx android.ModuleContext) map[string]string 149*e4a36f41SAndroid Build Coastguard Worker} 150*e4a36f41SAndroid Build Coastguard Worker 151*e4a36f41SAndroid Build Coastguard Workertype flaggableModuleBase struct { 152*e4a36f41SAndroid Build Coastguard Worker properties flaggableModuleProperties 153*e4a36f41SAndroid Build Coastguard Worker} 154*e4a36f41SAndroid Build Coastguard Worker 155*e4a36f41SAndroid Build Coastguard Workerfunc initFlaggableModule(m flaggableModule) { 156*e4a36f41SAndroid Build Coastguard Worker base := m.flagModuleBase() 157*e4a36f41SAndroid Build Coastguard Worker m.AddProperties(&base.properties) 158*e4a36f41SAndroid Build Coastguard Worker} 159*e4a36f41SAndroid Build Coastguard Worker 160*e4a36f41SAndroid Build Coastguard Workerfunc (f *flaggableModuleBase) flagModuleBase() *flaggableModuleBase { 161*e4a36f41SAndroid Build Coastguard Worker return f 162*e4a36f41SAndroid Build Coastguard Worker} 163*e4a36f41SAndroid Build Coastguard Worker 164*e4a36f41SAndroid Build Coastguard Workerfunc (f *flaggableModuleBase) flagDeps(ctx android.BottomUpMutatorContext) { 165*e4a36f41SAndroid Build Coastguard Worker ctx.AddDependency(ctx.Module(), buildFlagsDepTag, f.properties.Build_flags...) 166*e4a36f41SAndroid Build Coastguard Worker} 167*e4a36f41SAndroid Build Coastguard Worker 168*e4a36f41SAndroid Build Coastguard Worker// getBuildFlags returns a map from flag names to flag values. 169*e4a36f41SAndroid Build Coastguard Workerfunc (f *flaggableModuleBase) getBuildFlags(ctx android.ModuleContext) map[string]string { 170*e4a36f41SAndroid Build Coastguard Worker ret := make(map[string]string) 171*e4a36f41SAndroid Build Coastguard Worker ctx.VisitDirectDepsWithTag(buildFlagsDepTag, func(m android.Module) { 172*e4a36f41SAndroid Build Coastguard Worker if dep, ok := android.OtherModuleProvider(ctx, m, buildFlagsProviderKey); ok { 173*e4a36f41SAndroid Build Coastguard Worker maps.Copy(ret, dep.BuildFlags) 174*e4a36f41SAndroid Build Coastguard Worker } else { 175*e4a36f41SAndroid Build Coastguard Worker ctx.PropertyErrorf("build_flags", "unknown dependency %q", ctx.OtherModuleName(m)) 176*e4a36f41SAndroid Build Coastguard Worker } 177*e4a36f41SAndroid Build Coastguard Worker }) 178*e4a36f41SAndroid Build Coastguard Worker return ret 179*e4a36f41SAndroid Build Coastguard Worker} 180