blob: c7aeb321747e5ea994fb7adcc2bceea5cb3d14e9 [file] [log] [blame]
Inseob Kim6cd0ddd2023-10-25 23:48:16 +09001// Copyright (C) 2023 The Android Open Source Project
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 selinux
16
17import (
Inseob Kimbf7f4a42024-02-14 13:53:39 +090018 "maps"
19
Inseob Kim6cd0ddd2023-10-25 23:48:16 +090020 "android/soong/android"
Inseob Kimbf7f4a42024-02-14 13:53:39 +090021
22 "github.com/google/blueprint"
Inseob Kim6cd0ddd2023-10-25 23:48:16 +090023)
24
Inseob Kimbf7f4a42024-02-14 13:53:39 +090025var (
26 flagsDepTag = dependencyTag{name: "flags"}
27 buildFlagsDepTag = dependencyTag{name: "build_flags"}
28)
29
30func init() {
31 ctx := android.InitRegistrationContext
32 ctx.RegisterModuleType("se_flags", flagsFactory)
33 ctx.RegisterModuleType("se_flags_collector", flagsCollectorFactory)
34}
35
Inseob Kim6cd0ddd2023-10-25 23:48:16 +090036type flagsProperties struct {
Inseob Kimbf7f4a42024-02-14 13:53:39 +090037 // List of build time flags for flag-guarding.
Inseob Kim6cd0ddd2023-10-25 23:48:16 +090038 Flags []string
Inseob Kimbf7f4a42024-02-14 13:53:39 +090039
40 // List of se_flags_collector modules to export flags to.
41 Export_to []string
42}
43
44type flagsModule struct {
45 android.ModuleBase
46 properties flagsProperties
47}
48
49type flagsInfo struct {
50 Flags []string
51}
52
53var flagsProviderKey = blueprint.NewProvider[flagsInfo]()
54
55// se_flags contains a list of build time flags for sepolicy. Build time flags are defined under
56// .scl files (e.g. build/release/build_flags.scl). By importing flags with se_flags modules,
57// sepolicy rules can be guarded by `is_flag_enabled` / `is_flag_disabled` macro.
58//
59// For example, an Android.bp file could have:
60//
61// se_flags {
62// name: "aosp_selinux_flags",
63// flags: ["RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT"],
64// export_to: ["all_selinux_flags"],
65// }
66//
67// And then one could flag-guard .te file rules:
68//
69// is_flag_enabled(RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT, `
70// type vfio_handler, domain, coredomain;
71// binder_use(vfio_handler)
72// ')
73//
74// or contexts entries:
75//
76// is_flag_enabled(RELEASE_AVF_ENABLE_DEVICE_ASSIGNMENT, `
77// android.system.virtualizationservice_internal.IVfioHandler u:object_r:vfio_handler_service:s0
78// ')
79func flagsFactory() android.Module {
80 module := &flagsModule{}
81 module.AddProperties(&module.properties)
82 android.InitAndroidModule(module)
83 return module
84}
85
86func (f *flagsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
87 // dep se_flag_collector -> se_flags
88 for _, export := range f.properties.Export_to {
89 ctx.AddReverseDependency(ctx.Module(), flagsDepTag, export)
90 }
91}
92
93func (f *flagsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
94 android.SetProvider(ctx, flagsProviderKey, flagsInfo{
95 Flags: f.properties.Flags,
96 })
97}
98
99type buildFlagsInfo struct {
100 BuildFlags map[string]string
101}
102
103var buildFlagsProviderKey = blueprint.NewProvider[buildFlagsInfo]()
104
105type flagsCollectorModule struct {
106 android.ModuleBase
107 buildFlags map[string]string
108}
109
110// se_flags_collector module collects flags from exported se_flags modules (see export_to property
111// of se_flags modules), and then converts them into build-time flags. It will be used to generate
112// M4 macros to flag-guard sepolicy.
113func flagsCollectorFactory() android.Module {
114 module := &flagsCollectorModule{}
115 android.InitAndroidModule(module)
116 return module
117}
118
119func (f *flagsCollectorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
120 var flags []string
121 ctx.VisitDirectDepsWithTag(flagsDepTag, func(m android.Module) {
122 if dep, ok := android.OtherModuleProvider(ctx, m, flagsProviderKey); ok {
123 flags = append(flags, dep.Flags...)
124 } else {
125 ctx.ModuleErrorf("unknown dependency %q", ctx.OtherModuleName(m))
126 }
127 })
128 buildFlags := make(map[string]string)
129 for _, flag := range android.SortedUniqueStrings(flags) {
130 if val, ok := ctx.Config().GetBuildFlag(flag); ok {
131 buildFlags[flag] = val
132 }
133 }
134 android.SetProvider(ctx, buildFlagsProviderKey, buildFlagsInfo{
135 BuildFlags: buildFlags,
136 })
137}
138
139type flaggableModuleProperties struct {
140 // List of se_flag_collector modules to be passed to M4 macro.
141 Build_flags []string
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900142}
143
144type flaggableModule interface {
145 android.Module
146 flagModuleBase() *flaggableModuleBase
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900147 flagDeps(ctx android.BottomUpMutatorContext)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900148 getBuildFlags(ctx android.ModuleContext) map[string]string
149}
150
151type flaggableModuleBase struct {
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900152 properties flaggableModuleProperties
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900153}
154
155func initFlaggableModule(m flaggableModule) {
156 base := m.flagModuleBase()
157 m.AddProperties(&base.properties)
158}
159
160func (f *flaggableModuleBase) flagModuleBase() *flaggableModuleBase {
161 return f
162}
163
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900164func (f *flaggableModuleBase) flagDeps(ctx android.BottomUpMutatorContext) {
165 ctx.AddDependency(ctx.Module(), buildFlagsDepTag, f.properties.Build_flags...)
166}
167
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900168// getBuildFlags returns a map from flag names to flag values.
169func (f *flaggableModuleBase) getBuildFlags(ctx android.ModuleContext) map[string]string {
170 ret := make(map[string]string)
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900171 ctx.VisitDirectDepsWithTag(buildFlagsDepTag, func(m android.Module) {
172 if dep, ok := android.OtherModuleProvider(ctx, m, buildFlagsProviderKey); ok {
173 maps.Copy(ret, dep.BuildFlags)
174 } else {
175 ctx.PropertyErrorf("build_flags", "unknown dependency %q", ctx.OtherModuleName(m))
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900176 }
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900177 })
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900178 return ret
179}