blob: 7412df8ed27acc611a1f2fd54ae0cb4e92d90a90 [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 (
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090018 "os"
Inseob Kim0a707fa2021-12-09 23:35:11 +090019 "sort"
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090020 "strconv"
Inseob Kim0a707fa2021-12-09 23:35:11 +090021 "strings"
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090022
23 "github.com/google/blueprint/proptools"
24
25 "android/soong/android"
26)
27
28const (
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090029 MlsSens = 1
30 MlsCats = 1024
31 PolicyVers = 30
32)
33
Inseob Kim0a707fa2021-12-09 23:35:11 +090034// This order should be kept. checkpolicy syntax requires it.
35var policyConfOrder = []string{
36 "security_classes",
37 "initial_sids",
38 "access_vectors",
39 "global_macros",
40 "neverallow_macros",
41 "mls_macros",
42 "mls_decl",
43 "mls",
44 "policy_capabilities",
45 "te_macros",
Inseob Kim0a707fa2021-12-09 23:35:11 +090046 "ioctl_defines",
47 "ioctl_macros",
Inseob Kim1e796342022-06-09 11:26:35 +090048 "attributes|*.te",
Inseob Kim0a707fa2021-12-09 23:35:11 +090049 "roles_decl",
50 "roles",
51 "users",
52 "initial_sid_contexts",
53 "fs_use",
54 "genfs_contexts",
55 "port_contexts",
56}
57
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090058func init() {
59 android.RegisterModuleType("se_policy_conf", policyConfFactory)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +090060 android.RegisterModuleType("se_policy_conf_defaults", policyConfDefaultFactory)
Inseob Kimdf1a0de2021-03-17 19:05:02 +090061 android.RegisterModuleType("se_policy_cil", policyCilFactory)
Inseob Kimb9d05112021-09-27 13:13:46 +000062 android.RegisterModuleType("se_policy_binary", policyBinaryFactory)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090063}
64
65type policyConfProperties struct {
66 // Name of the output. Default is {module_name}
67 Stem *string
68
69 // Policy files to be compiled to cil file.
70 Srcs []string `android:"path"`
71
72 // Target build variant (user / userdebug / eng). Default follows the current lunch target
73 Build_variant *string
74
75 // Whether to exclude build test or not. Default is false
76 Exclude_build_test *bool
77
78 // Whether to include asan specific policies or not. Default follows the current lunch target
79 With_asan *bool
80
81 // Whether to build CTS specific policy or not. Default is false
82 Cts *bool
83
Inseob Kim5bbcd682021-12-28 14:57:03 +090084 // Whether to build recovery specific policy or not. Default is false
85 Target_recovery *bool
86
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090087 // Whether this module is directly installable to one of the partitions. Default is true
88 Installable *bool
Inseob Kim6e384f32022-03-10 13:15:05 +090089
90 // Desired number of MLS categories. Defaults to 1024
91 Mls_cats *int64
Inseob Kim8697fc82024-04-16 14:45:32 +090092
93 // Whether to turn on board_api_level guard or not. Defaults to false
94 Board_api_level_guard *bool
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090095}
96
97type policyConf struct {
98 android.ModuleBase
Inseob Kim6cd0ddd2023-10-25 23:48:16 +090099 android.DefaultableModuleBase
100 flaggableModuleBase
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900101
102 properties policyConfProperties
103
104 installSource android.Path
105 installPath android.InstallPath
106}
107
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900108var _ flaggableModule = (*policyConf)(nil)
109
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900110// se_policy_conf merges collection of policy files into a policy.conf file to be processed by
111// checkpolicy.
112func policyConfFactory() android.Module {
113 c := &policyConf{}
114 c.AddProperties(&c.properties)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900115 initFlaggableModule(c)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900116 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900117 android.InitDefaultableModule(c)
118 return c
119}
120
121type policyConfDefaults struct {
122 android.ModuleBase
123 android.DefaultsModuleBase
124}
125
126// se_policy_conf_defaults provides a set of properties that can be inherited by other
127// se_policy_conf_defaults modules. A module can use the properties from a se_policy_conf_defaults
128// using `defaults: ["<:default_module_name>"]`. Properties of both modules are merged (when
129// possible) by prepending the default module's values to the depending module's values.
130func policyConfDefaultFactory() android.Module {
131 c := &policyConfDefaults{}
132 c.AddProperties(
133 &policyConfProperties{},
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900134 &flaggableModuleProperties{},
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900135 )
136 android.InitDefaultsModule(c)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900137 return c
138}
139
140func (c *policyConf) installable() bool {
141 return proptools.BoolDefault(c.properties.Installable, true)
142}
143
144func (c *policyConf) stem() string {
145 return proptools.StringDefault(c.properties.Stem, c.Name())
146}
147
148func (c *policyConf) buildVariant(ctx android.ModuleContext) string {
149 if variant := proptools.String(c.properties.Build_variant); variant != "" {
150 return variant
151 }
152 if ctx.Config().Eng() {
153 return "eng"
154 }
155 if ctx.Config().Debuggable() {
156 return "userdebug"
157 }
158 return "user"
159}
160
161func (c *policyConf) cts() bool {
162 return proptools.Bool(c.properties.Cts)
163}
164
Inseob Kim5bbcd682021-12-28 14:57:03 +0900165func (c *policyConf) isTargetRecovery() bool {
166 return proptools.Bool(c.properties.Target_recovery)
167}
168
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900169func (c *policyConf) withAsan(ctx android.ModuleContext) string {
170 isAsanDevice := android.InList("address", ctx.Config().SanitizeDevice())
171 return strconv.FormatBool(proptools.BoolDefault(c.properties.With_asan, isAsanDevice))
172}
173
174func (c *policyConf) sepolicySplit(ctx android.ModuleContext) string {
175 if c.cts() {
176 return "cts"
177 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900178 if c.isTargetRecovery() {
179 return "false"
180 }
Steven Moreland721f5af2023-05-31 21:54:51 +0000181 return strconv.FormatBool(true)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900182}
183
184func (c *policyConf) compatibleProperty(ctx android.ModuleContext) string {
185 if c.cts() {
186 return "cts"
187 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900188 if c.isTargetRecovery() {
189 return "false"
190 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900191 return "true"
192}
193
194func (c *policyConf) trebleSyspropNeverallow(ctx android.ModuleContext) string {
195 if c.cts() {
196 return "cts"
197 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900198 if c.isTargetRecovery() {
199 return "false"
200 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900201 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenTrebleSyspropNeverallow())
202}
203
204func (c *policyConf) enforceSyspropOwner(ctx android.ModuleContext) string {
205 if c.cts() {
206 return "cts"
207 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900208 if c.isTargetRecovery() {
209 return "false"
210 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900211 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenEnforceSyspropOwner())
212}
213
Hridya Valsarajua885dd82021-04-26 16:32:17 -0700214func (c *policyConf) enforceDebugfsRestrictions(ctx android.ModuleContext) string {
215 if c.cts() {
216 return "cts"
217 }
218 return strconv.FormatBool(ctx.DeviceConfig().BuildDebugfsRestrictionsEnabled())
219}
220
Inseob Kim6e384f32022-03-10 13:15:05 +0900221func (c *policyConf) mlsCats() int {
222 return proptools.IntDefault(c.properties.Mls_cats, MlsCats)
223}
224
Inseob Kim8697fc82024-04-16 14:45:32 +0900225func (c *policyConf) boardApiLevel(ctx android.ModuleContext) string {
226 if proptools.Bool(c.properties.Board_api_level_guard) {
227 return ctx.Config().VendorApiLevel()
228 }
229 // aribtrary value greater than any other vendor API levels
230 return "1000000"
231}
232
Inseob Kim0a707fa2021-12-09 23:35:11 +0900233func findPolicyConfOrder(name string) int {
234 for idx, pattern := range policyConfOrder {
Inseob Kim1e796342022-06-09 11:26:35 +0900235 // We could use regexp but it seems like an overkill
236 if pattern == "attributes|*.te" && (name == "attributes" || strings.HasSuffix(name, ".te")) {
237 return idx
238 } else if pattern == name {
Inseob Kim0a707fa2021-12-09 23:35:11 +0900239 return idx
240 }
241 }
242 // name is not matched
243 return len(policyConfOrder)
244}
245
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900246func (c *policyConf) transformPolicyToConf(ctx android.ModuleContext) android.OutputPath {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900247 conf := pathForModuleOut(ctx, c.stem())
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900248 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim0a707fa2021-12-09 23:35:11 +0900249
250 srcs := android.PathsForModuleSrc(ctx, c.properties.Srcs)
251 sort.SliceStable(srcs, func(x, y int) bool {
252 return findPolicyConfOrder(srcs[x].Base()) < findPolicyConfOrder(srcs[y].Base())
253 })
254
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900255 flags := c.getBuildFlags(ctx)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900256 rule.Command().Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
257 Flag("--fatal-warnings").
258 FlagForEachArg("-D ", ctx.DeviceConfig().SepolicyM4Defs()).
259 FlagWithArg("-D mls_num_sens=", strconv.Itoa(MlsSens)).
Inseob Kim6e384f32022-03-10 13:15:05 +0900260 FlagWithArg("-D mls_num_cats=", strconv.Itoa(c.mlsCats())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900261 FlagWithArg("-D target_arch=", ctx.DeviceConfig().DeviceArch()).
262 FlagWithArg("-D target_with_asan=", c.withAsan(ctx)).
Inseob Kim4360c192021-03-23 20:52:53 +0900263 FlagWithArg("-D target_with_dexpreopt=", strconv.FormatBool(ctx.DeviceConfig().WithDexpreopt())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900264 FlagWithArg("-D target_with_native_coverage=", strconv.FormatBool(ctx.DeviceConfig().ClangCoverageEnabled() || ctx.DeviceConfig().GcovCoverageEnabled())).
265 FlagWithArg("-D target_build_variant=", c.buildVariant(ctx)).
266 FlagWithArg("-D target_full_treble=", c.sepolicySplit(ctx)).
267 FlagWithArg("-D target_compatible_property=", c.compatibleProperty(ctx)).
268 FlagWithArg("-D target_treble_sysprop_neverallow=", c.trebleSyspropNeverallow(ctx)).
269 FlagWithArg("-D target_enforce_sysprop_owner=", c.enforceSyspropOwner(ctx)).
270 FlagWithArg("-D target_exclude_build_test=", strconv.FormatBool(proptools.Bool(c.properties.Exclude_build_test))).
271 FlagWithArg("-D target_requires_insecure_execmem_for_swiftshader=", strconv.FormatBool(ctx.DeviceConfig().RequiresInsecureExecmemForSwiftshader())).
Hridya Valsarajua885dd82021-04-26 16:32:17 -0700272 FlagWithArg("-D target_enforce_debugfs_restriction=", c.enforceDebugfsRestrictions(ctx)).
Inseob Kim5bbcd682021-12-28 14:57:03 +0900273 FlagWithArg("-D target_recovery=", strconv.FormatBool(c.isTargetRecovery())).
Inseob Kim8697fc82024-04-16 14:45:32 +0900274 FlagWithArg("-D target_board_api_level=", c.boardApiLevel(ctx)).
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900275 Flags(flagsToM4Macros(flags)).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900276 Flag("-s").
Inseob Kim0a707fa2021-12-09 23:35:11 +0900277 Inputs(srcs).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900278 Text("> ").Output(conf)
279
280 rule.Build("conf", "Transform policy to conf: "+ctx.ModuleName())
281 return conf
282}
283
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900284func (c *policyConf) DepsMutator(ctx android.BottomUpMutatorContext) {
285 c.flagDeps(ctx)
286}
287
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900288func (c *policyConf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900289 if !c.installable() {
290 c.SkipInstall()
291 }
Inseob Kim31db2742021-06-08 10:31:09 +0900292
293 c.installSource = c.transformPolicyToConf(ctx)
294 c.installPath = android.PathForModuleInstall(ctx, "etc")
295 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
mrziwangcb3f5502024-06-06 10:04:23 -0700296
297 ctx.SetOutputFiles(android.Paths{c.installSource}, "")
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900298}
299
300func (c *policyConf) AndroidMkEntries() []android.AndroidMkEntries {
301 return []android.AndroidMkEntries{android.AndroidMkEntries{
302 OutputFile: android.OptionalPathForPath(c.installSource),
303 Class: "ETC",
304 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
305 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
306 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800307 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900308 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
309 },
310 },
311 }}
312}
313
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900314type policyCilProperties struct {
315 // Name of the output. Default is {module_name}
316 Stem *string
317
318 // Policy file to be compiled to cil file.
319 Src *string `android:"path"`
320
Sandro143988d2022-08-05 11:38:56 +0000321 // If true, the input policy file is a binary policy that will be decompiled to a cil file.
322 // Defaults to false.
323 Decompile_binary *bool
324
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900325 // Additional cil files to be added in the end of the output. This is to support workarounds
326 // which are not supported by the policy language.
327 Additional_cil_files []string `android:"path"`
328
329 // Cil files to be filtered out by the filter_out tool of "build_sepolicy". Used to build
330 // exported policies
331 Filter_out []string `android:"path"`
332
333 // Whether to remove line markers (denoted by ;;) out of compiled cil files. Defaults to false
334 Remove_line_marker *bool
335
336 // Whether to run secilc to check compiled policy or not. Defaults to true
337 Secilc_check *bool
338
339 // Whether to ignore neverallow when running secilc check. Defaults to
340 // SELINUX_IGNORE_NEVERALLOWS.
341 Ignore_neverallow *bool
342
343 // Whether this module is directly installable to one of the partitions. Default is true
344 Installable *bool
345}
346
347type policyCil struct {
348 android.ModuleBase
349
350 properties policyCilProperties
351
352 installSource android.Path
353 installPath android.InstallPath
354}
355
356// se_policy_cil compiles a policy.conf file to a cil file with checkpolicy, and optionally runs
357// secilc to check the output cil file. Affected by SELINUX_IGNORE_NEVERALLOWS.
358func policyCilFactory() android.Module {
359 c := &policyCil{}
360 c.AddProperties(&c.properties)
361 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
362 return c
363}
364
365func (c *policyCil) Installable() bool {
366 return proptools.BoolDefault(c.properties.Installable, true)
367}
368
369func (c *policyCil) stem() string {
370 return proptools.StringDefault(c.properties.Stem, c.Name())
371}
372
373func (c *policyCil) compileConfToCil(ctx android.ModuleContext, conf android.Path) android.OutputPath {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900374 cil := pathForModuleOut(ctx, c.stem())
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900375 rule := android.NewRuleBuilder(pctx, ctx)
Sandro143988d2022-08-05 11:38:56 +0000376 checkpolicyCmd := rule.Command().BuiltTool("checkpolicy").
Lokesh Gidra1269a172022-08-01 17:20:38 +0000377 Flag("-C"). // Write CIL
378 Flag("-M"). // Enable MLS
379 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
380 FlagWithOutput("-o ", cil).
381 Input(conf)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900382
Sandro143988d2022-08-05 11:38:56 +0000383 if proptools.Bool(c.properties.Decompile_binary) {
384 checkpolicyCmd.Flag("-b") // Read binary
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900385 }
386
387 if len(c.properties.Filter_out) > 0 {
388 rule.Command().BuiltTool("build_sepolicy").
389 Text("filter_out").
390 Flag("-f").
391 Inputs(android.PathsForModuleSrc(ctx, c.properties.Filter_out)).
392 FlagWithOutput("-t ", cil)
393 }
394
Sandro143988d2022-08-05 11:38:56 +0000395 if len(c.properties.Additional_cil_files) > 0 {
396 rule.Command().Text("cat").
397 Inputs(android.PathsForModuleSrc(ctx, c.properties.Additional_cil_files)).
398 Text(">> ").Output(cil)
399 }
400
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900401 if proptools.Bool(c.properties.Remove_line_marker) {
402 rule.Command().Text("grep -v").
403 Text(proptools.ShellEscape(";;")).
404 Text(cil.String()).
405 Text(">").
406 Text(cil.String() + ".tmp").
407 Text("&& mv").
408 Text(cil.String() + ".tmp").
409 Text(cil.String())
410 }
411
412 if proptools.BoolDefault(c.properties.Secilc_check, true) {
413 secilcCmd := rule.Command().BuiltTool("secilc").
414 Flag("-m"). // Multiple decls
415 FlagWithArg("-M ", "true"). // Enable MLS
416 Flag("-G"). // expand and remove auto generated attributes
417 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
418 Inputs(android.PathsForModuleSrc(ctx, c.properties.Filter_out)). // Also add cil files which are filtered out
419 Text(cil.String()).
420 FlagWithArg("-o ", os.DevNull).
421 FlagWithArg("-f ", os.DevNull)
422
423 if proptools.BoolDefault(c.properties.Ignore_neverallow, ctx.Config().SelinuxIgnoreNeverallows()) {
424 secilcCmd.Flag("-N")
425 }
426 }
427
428 rule.Build("cil", "Building cil for "+ctx.ModuleName())
429 return cil
430}
431
432func (c *policyCil) GenerateAndroidBuildActions(ctx android.ModuleContext) {
433 if proptools.String(c.properties.Src) == "" {
434 ctx.PropertyErrorf("src", "must be specified")
435 return
436 }
437 conf := android.PathForModuleSrc(ctx, *c.properties.Src)
438 cil := c.compileConfToCil(ctx, conf)
439
Inseob Kim31db2742021-06-08 10:31:09 +0900440 if !c.Installable() {
441 c.SkipInstall()
442 }
443
Inseob Kim6cc75f42021-04-29 13:53:20 +0000444 if c.InstallInDebugRamdisk() {
445 // for userdebug_plat_sepolicy.cil
446 c.installPath = android.PathForModuleInstall(ctx)
447 } else {
448 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
449 }
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900450 c.installSource = cil
451 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
mrziwangcb3f5502024-06-06 10:04:23 -0700452
453 ctx.SetOutputFiles(android.Paths{c.installSource}, "")
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900454}
455
456func (c *policyCil) AndroidMkEntries() []android.AndroidMkEntries {
457 return []android.AndroidMkEntries{android.AndroidMkEntries{
458 OutputFile: android.OptionalPathForPath(c.installSource),
459 Class: "ETC",
460 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
461 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
462 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.Installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800463 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900464 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
465 },
466 },
467 }}
468}
469
Inseob Kimb9d05112021-09-27 13:13:46 +0000470type policyBinaryProperties struct {
471 // Name of the output. Default is {module_name}
472 Stem *string
473
474 // Cil files to be compiled.
475 Srcs []string `android:"path"`
476
477 // Whether to ignore neverallow when running secilc check. Defaults to
478 // SELINUX_IGNORE_NEVERALLOWS.
479 Ignore_neverallow *bool
480
481 // Whether this module is directly installable to one of the partitions. Default is true
482 Installable *bool
Jiyong Parkef567212022-12-05 14:06:47 +0900483
484 // List of domains that are allowed to be in permissive mode on user builds.
485 Permissive_domains_on_user_builds []string
Inseob Kimb9d05112021-09-27 13:13:46 +0000486}
487
488type policyBinary struct {
489 android.ModuleBase
490
491 properties policyBinaryProperties
492
493 installSource android.Path
494 installPath android.InstallPath
495}
496
497// se_policy_binary compiles cil files to a binary sepolicy file with secilc. Usually sources of
498// se_policy_binary come from outputs of se_policy_cil modules.
499func policyBinaryFactory() android.Module {
500 c := &policyBinary{}
501 c.AddProperties(&c.properties)
502 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
503 return c
504}
505
Inseob Kim5bbcd682021-12-28 14:57:03 +0900506func (c *policyBinary) InstallInRoot() bool {
507 return c.InstallInRecovery()
508}
509
Inseob Kimb9d05112021-09-27 13:13:46 +0000510func (c *policyBinary) Installable() bool {
511 return proptools.BoolDefault(c.properties.Installable, true)
512}
513
514func (c *policyBinary) stem() string {
515 return proptools.StringDefault(c.properties.Stem, c.Name())
516}
517
518func (c *policyBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
519 if len(c.properties.Srcs) == 0 {
520 ctx.PropertyErrorf("srcs", "must be specified")
521 return
522 }
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900523 bin := pathForModuleOut(ctx, c.stem()+"_policy")
Inseob Kimb9d05112021-09-27 13:13:46 +0000524 rule := android.NewRuleBuilder(pctx, ctx)
525 secilcCmd := rule.Command().BuiltTool("secilc").
526 Flag("-m"). // Multiple decls
527 FlagWithArg("-M ", "true"). // Enable MLS
528 Flag("-G"). // expand and remove auto generated attributes
529 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
530 Inputs(android.PathsForModuleSrc(ctx, c.properties.Srcs)).
531 FlagWithOutput("-o ", bin).
532 FlagWithArg("-f ", os.DevNull)
533
534 if proptools.BoolDefault(c.properties.Ignore_neverallow, ctx.Config().SelinuxIgnoreNeverallows()) {
535 secilcCmd.Flag("-N")
536 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900537 rule.Temporary(bin)
Inseob Kimb9d05112021-09-27 13:13:46 +0000538
Inseob Kim3d5f9252021-12-21 20:42:35 +0900539 // permissive check is performed only in user build (not debuggable).
540 if !ctx.Config().Debuggable() {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900541 permissiveDomains := pathForModuleOut(ctx, c.stem()+"_permissive")
Jiyong Parkef567212022-12-05 14:06:47 +0900542 cmd := rule.Command().BuiltTool("sepolicy-analyze").
Inseob Kim3d5f9252021-12-21 20:42:35 +0900543 Input(bin).
Jiyong Parkef567212022-12-05 14:06:47 +0900544 Text("permissive")
545 // Filter-out domains listed in permissive_domains_on_user_builds
546 allowedDomains := c.properties.Permissive_domains_on_user_builds
547 if len(allowedDomains) != 0 {
548 cmd.Text("| { grep -Fxv")
549 for _, d := range allowedDomains {
550 cmd.FlagWithArg("-e ", proptools.ShellEscape(d))
551 }
552 cmd.Text(" || true; }") // no match doesn't fail the cmd
553 }
554 cmd.Text(" > ").Output(permissiveDomains)
Christian Oder15189ab2020-01-28 17:56:07 +0100555 rule.Command().Text("sed").FlagWithArg("-i ", "'/backuptool/d'").Input(permissiveDomains)
556 rule.Command().Text("sed").FlagWithArg("-i ", "'/recovery/d'").Input(permissiveDomains)
Inseob Kim3d5f9252021-12-21 20:42:35 +0900557 rule.Temporary(permissiveDomains)
558
559 msg := `==========\n` +
560 `ERROR: permissive domains not allowed in user builds\n` +
561 `List of invalid domains:`
562
563 rule.Command().Text("if test").
564 FlagWithInput("-s ", permissiveDomains).
565 Text("; then echo").
566 Flag("-e").
567 Text(`"` + msg + `"`).
568 Text("&& cat ").
569 Input(permissiveDomains).
570 Text("; exit 1; fi")
571 }
572
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900573 out := pathForModuleOut(ctx, c.stem())
Inseob Kim3d5f9252021-12-21 20:42:35 +0900574 rule.Command().Text("cp").
575 Flag("-f").
576 Input(bin).
577 Output(out)
578
579 rule.DeleteTemporaryFiles()
Inseob Kimb9d05112021-09-27 13:13:46 +0000580 rule.Build("secilc", "Compiling cil files for "+ctx.ModuleName())
581
582 if !c.Installable() {
583 c.SkipInstall()
584 }
585
Inseob Kim5bbcd682021-12-28 14:57:03 +0900586 if c.InstallInRecovery() {
587 // install in root
588 c.installPath = android.PathForModuleInstall(ctx)
589 } else {
590 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
591 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900592 c.installSource = out
Inseob Kimb9d05112021-09-27 13:13:46 +0000593 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
mrziwangcb3f5502024-06-06 10:04:23 -0700594
595 ctx.SetOutputFiles(android.Paths{c.installSource}, "")
Inseob Kimb9d05112021-09-27 13:13:46 +0000596}
597
598func (c *policyBinary) AndroidMkEntries() []android.AndroidMkEntries {
599 return []android.AndroidMkEntries{android.AndroidMkEntries{
600 OutputFile: android.OptionalPathForPath(c.installSource),
601 Class: "ETC",
602 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
603 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
604 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.Installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800605 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kimb9d05112021-09-27 13:13:46 +0000606 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
607 },
608 },
609 }}
610}