blob: f7686c0d3fa4f239000e02100a48d50e91a8aace [file] [log] [blame]
Inseob Kim7e8bd1e2021-03-17 18:59:43 +09001// Copyright (C) 2021 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 (
18 "fmt"
19 "os"
20 "strconv"
21
22 "github.com/google/blueprint/proptools"
23
24 "android/soong/android"
25)
26
27const (
28 // TODO: sync with Android.mk
29 MlsSens = 1
30 MlsCats = 1024
31 PolicyVers = 30
32)
33
34func init() {
35 android.RegisterModuleType("se_policy_conf", policyConfFactory)
36}
37
38type policyConfProperties struct {
39 // Name of the output. Default is {module_name}
40 Stem *string
41
42 // Policy files to be compiled to cil file.
43 Srcs []string `android:"path"`
44
45 // Target build variant (user / userdebug / eng). Default follows the current lunch target
46 Build_variant *string
47
48 // Whether to exclude build test or not. Default is false
49 Exclude_build_test *bool
50
51 // Whether to include asan specific policies or not. Default follows the current lunch target
52 With_asan *bool
53
54 // Whether to build CTS specific policy or not. Default is false
55 Cts *bool
56
57 // Whether this module is directly installable to one of the partitions. Default is true
58 Installable *bool
59}
60
61type policyConf struct {
62 android.ModuleBase
63
64 properties policyConfProperties
65
66 installSource android.Path
67 installPath android.InstallPath
68}
69
70// se_policy_conf merges collection of policy files into a policy.conf file to be processed by
71// checkpolicy.
72func policyConfFactory() android.Module {
73 c := &policyConf{}
74 c.AddProperties(&c.properties)
75 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
76 return c
77}
78
79func (c *policyConf) installable() bool {
80 return proptools.BoolDefault(c.properties.Installable, true)
81}
82
83func (c *policyConf) stem() string {
84 return proptools.StringDefault(c.properties.Stem, c.Name())
85}
86
87func (c *policyConf) buildVariant(ctx android.ModuleContext) string {
88 if variant := proptools.String(c.properties.Build_variant); variant != "" {
89 return variant
90 }
91 if ctx.Config().Eng() {
92 return "eng"
93 }
94 if ctx.Config().Debuggable() {
95 return "userdebug"
96 }
97 return "user"
98}
99
100func (c *policyConf) cts() bool {
101 return proptools.Bool(c.properties.Cts)
102}
103
104func (c *policyConf) withAsan(ctx android.ModuleContext) string {
105 isAsanDevice := android.InList("address", ctx.Config().SanitizeDevice())
106 return strconv.FormatBool(proptools.BoolDefault(c.properties.With_asan, isAsanDevice))
107}
108
109func (c *policyConf) sepolicySplit(ctx android.ModuleContext) string {
110 if c.cts() {
111 return "cts"
112 }
113 return strconv.FormatBool(ctx.DeviceConfig().SepolicySplit())
114}
115
116func (c *policyConf) compatibleProperty(ctx android.ModuleContext) string {
117 if c.cts() {
118 return "cts"
119 }
120 return "true"
121}
122
123func (c *policyConf) trebleSyspropNeverallow(ctx android.ModuleContext) string {
124 if c.cts() {
125 return "cts"
126 }
127 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenTrebleSyspropNeverallow())
128}
129
130func (c *policyConf) enforceSyspropOwner(ctx android.ModuleContext) string {
131 if c.cts() {
132 return "cts"
133 }
134 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenEnforceSyspropOwner())
135}
136
137func (c *policyConf) transformPolicyToConf(ctx android.ModuleContext) android.OutputPath {
138 conf := android.PathForModuleOut(ctx, "conf").OutputPath
139 rule := android.NewRuleBuilder(pctx, ctx)
140 rule.Command().Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
141 Flag("--fatal-warnings").
142 FlagForEachArg("-D ", ctx.DeviceConfig().SepolicyM4Defs()).
143 FlagWithArg("-D mls_num_sens=", strconv.Itoa(MlsSens)).
144 FlagWithArg("-D mls_num_cats=", strconv.Itoa(MlsCats)).
145 FlagWithArg("-D target_arch=", ctx.DeviceConfig().DeviceArch()).
146 FlagWithArg("-D target_with_asan=", c.withAsan(ctx)).
147 FlagWithArg("-D target_with_native_coverage=", strconv.FormatBool(ctx.DeviceConfig().ClangCoverageEnabled() || ctx.DeviceConfig().GcovCoverageEnabled())).
148 FlagWithArg("-D target_build_variant=", c.buildVariant(ctx)).
149 FlagWithArg("-D target_full_treble=", c.sepolicySplit(ctx)).
150 FlagWithArg("-D target_compatible_property=", c.compatibleProperty(ctx)).
151 FlagWithArg("-D target_treble_sysprop_neverallow=", c.trebleSyspropNeverallow(ctx)).
152 FlagWithArg("-D target_enforce_sysprop_owner=", c.enforceSyspropOwner(ctx)).
153 FlagWithArg("-D target_exclude_build_test=", strconv.FormatBool(proptools.Bool(c.properties.Exclude_build_test))).
154 FlagWithArg("-D target_requires_insecure_execmem_for_swiftshader=", strconv.FormatBool(ctx.DeviceConfig().RequiresInsecureExecmemForSwiftshader())).
155 Flag("-s").
156 Inputs(android.PathsForModuleSrc(ctx, c.properties.Srcs)).
157 Text("> ").Output(conf)
158
159 rule.Build("conf", "Transform policy to conf: "+ctx.ModuleName())
160 return conf
161}
162
163func (c *policyConf) DepsMutator(ctx android.BottomUpMutatorContext) {
164 // do nothing
165}
166
167func (c *policyConf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
168 c.installSource = c.transformPolicyToConf(ctx)
169 c.installPath = android.PathForModuleInstall(ctx, "etc")
170 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
171
172 if !c.installable() {
173 c.SkipInstall()
174 }
175}
176
177func (c *policyConf) AndroidMkEntries() []android.AndroidMkEntries {
178 return []android.AndroidMkEntries{android.AndroidMkEntries{
179 OutputFile: android.OptionalPathForPath(c.installSource),
180 Class: "ETC",
181 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
182 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
183 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.installable())
184 entries.SetPath("LOCAL_MODULE_PATH", c.installPath.ToMakePath())
185 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
186 },
187 },
188 }}
189}
190
191func (c *policyConf) OutputFiles(tag string) (android.Paths, error) {
192 if tag == "" {
193 return android.Paths{c.installSource}, nil
194 }
195 return nil, fmt.Errorf("Unknown tag %q", tag)
196}
197
198var _ android.OutputFileProducer = (*policyConf)(nil)