xref: /aosp_15_r20/system/sepolicy/build/soong/flags.go (revision e4a36f4174b17bbab9dc043f4a65dc8d87377290)
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