blob: 29685ea7606e4dd49c0aaec063fe424c6da98e8d [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{
Inseob Kim113f4d62024-07-18 11:29:51 +090036 "flagging_macros",
Inseob Kim0a707fa2021-12-09 23:35:11 +090037 "security_classes",
38 "initial_sids",
39 "access_vectors",
40 "global_macros",
41 "neverallow_macros",
42 "mls_macros",
43 "mls_decl",
44 "mls",
45 "policy_capabilities",
46 "te_macros",
Inseob Kim0a707fa2021-12-09 23:35:11 +090047 "ioctl_defines",
48 "ioctl_macros",
Inseob Kim1e796342022-06-09 11:26:35 +090049 "attributes|*.te",
Inseob Kim0a707fa2021-12-09 23:35:11 +090050 "roles_decl",
51 "roles",
52 "users",
53 "initial_sid_contexts",
54 "fs_use",
55 "genfs_contexts",
56 "port_contexts",
57}
58
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090059func init() {
60 android.RegisterModuleType("se_policy_conf", policyConfFactory)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +090061 android.RegisterModuleType("se_policy_conf_defaults", policyConfDefaultFactory)
Inseob Kimdf1a0de2021-03-17 19:05:02 +090062 android.RegisterModuleType("se_policy_cil", policyCilFactory)
Inseob Kimb9d05112021-09-27 13:13:46 +000063 android.RegisterModuleType("se_policy_binary", policyBinaryFactory)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090064}
65
66type policyConfProperties struct {
67 // Name of the output. Default is {module_name}
68 Stem *string
69
70 // Policy files to be compiled to cil file.
71 Srcs []string `android:"path"`
72
73 // Target build variant (user / userdebug / eng). Default follows the current lunch target
74 Build_variant *string
75
76 // Whether to exclude build test or not. Default is false
77 Exclude_build_test *bool
78
79 // Whether to include asan specific policies or not. Default follows the current lunch target
80 With_asan *bool
81
82 // Whether to build CTS specific policy or not. Default is false
83 Cts *bool
84
Inseob Kim5bbcd682021-12-28 14:57:03 +090085 // Whether to build recovery specific policy or not. Default is false
86 Target_recovery *bool
87
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090088 // Whether this module is directly installable to one of the partitions. Default is true
89 Installable *bool
Inseob Kim6e384f32022-03-10 13:15:05 +090090
91 // Desired number of MLS categories. Defaults to 1024
92 Mls_cats *int64
Inseob Kim8697fc82024-04-16 14:45:32 +090093
Inseob Kim007f0ae2024-07-18 10:29:52 +090094 // Board api level of policy files. Set "vendor" for RELEASE_BOARD_API_LEVEL, "system" for
95 // turning off the guard, or a direct version string (e.g. "202404"). Defaults to "system"
96 Board_api_level *string
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090097}
98
99type policyConf struct {
100 android.ModuleBase
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900101 android.DefaultableModuleBase
102 flaggableModuleBase
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900103
104 properties policyConfProperties
105
106 installSource android.Path
107 installPath android.InstallPath
108}
109
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900110var _ flaggableModule = (*policyConf)(nil)
111
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900112// se_policy_conf merges collection of policy files into a policy.conf file to be processed by
113// checkpolicy.
114func policyConfFactory() android.Module {
115 c := &policyConf{}
116 c.AddProperties(&c.properties)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900117 initFlaggableModule(c)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900118 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900119 android.InitDefaultableModule(c)
120 return c
121}
122
123type policyConfDefaults struct {
124 android.ModuleBase
125 android.DefaultsModuleBase
126}
127
128// se_policy_conf_defaults provides a set of properties that can be inherited by other
129// se_policy_conf_defaults modules. A module can use the properties from a se_policy_conf_defaults
130// using `defaults: ["<:default_module_name>"]`. Properties of both modules are merged (when
131// possible) by prepending the default module's values to the depending module's values.
132func policyConfDefaultFactory() android.Module {
133 c := &policyConfDefaults{}
134 c.AddProperties(
135 &policyConfProperties{},
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900136 &flaggableModuleProperties{},
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900137 )
138 android.InitDefaultsModule(c)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900139 return c
140}
141
142func (c *policyConf) installable() bool {
143 return proptools.BoolDefault(c.properties.Installable, true)
144}
145
146func (c *policyConf) stem() string {
147 return proptools.StringDefault(c.properties.Stem, c.Name())
148}
149
150func (c *policyConf) buildVariant(ctx android.ModuleContext) string {
151 if variant := proptools.String(c.properties.Build_variant); variant != "" {
152 return variant
153 }
154 if ctx.Config().Eng() {
155 return "eng"
156 }
157 if ctx.Config().Debuggable() {
158 return "userdebug"
159 }
160 return "user"
161}
162
163func (c *policyConf) cts() bool {
164 return proptools.Bool(c.properties.Cts)
165}
166
Inseob Kim5bbcd682021-12-28 14:57:03 +0900167func (c *policyConf) isTargetRecovery() bool {
168 return proptools.Bool(c.properties.Target_recovery)
169}
170
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900171func (c *policyConf) withAsan(ctx android.ModuleContext) string {
172 isAsanDevice := android.InList("address", ctx.Config().SanitizeDevice())
173 return strconv.FormatBool(proptools.BoolDefault(c.properties.With_asan, isAsanDevice))
174}
175
176func (c *policyConf) sepolicySplit(ctx android.ModuleContext) string {
177 if c.cts() {
178 return "cts"
179 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900180 if c.isTargetRecovery() {
181 return "false"
182 }
Steven Moreland721f5af2023-05-31 21:54:51 +0000183 return strconv.FormatBool(true)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900184}
185
186func (c *policyConf) compatibleProperty(ctx android.ModuleContext) string {
187 if c.cts() {
188 return "cts"
189 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900190 if c.isTargetRecovery() {
191 return "false"
192 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900193 return "true"
194}
195
196func (c *policyConf) trebleSyspropNeverallow(ctx android.ModuleContext) string {
197 if c.cts() {
198 return "cts"
199 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900200 if c.isTargetRecovery() {
201 return "false"
202 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900203 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenTrebleSyspropNeverallow())
204}
205
206func (c *policyConf) enforceSyspropOwner(ctx android.ModuleContext) string {
207 if c.cts() {
208 return "cts"
209 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900210 if c.isTargetRecovery() {
211 return "false"
212 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900213 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenEnforceSyspropOwner())
214}
215
Hridya Valsarajua885dd82021-04-26 16:32:17 -0700216func (c *policyConf) enforceDebugfsRestrictions(ctx android.ModuleContext) string {
217 if c.cts() {
218 return "cts"
219 }
220 return strconv.FormatBool(ctx.DeviceConfig().BuildDebugfsRestrictionsEnabled())
221}
222
Inseob Kim6e384f32022-03-10 13:15:05 +0900223func (c *policyConf) mlsCats() int {
224 return proptools.IntDefault(c.properties.Mls_cats, MlsCats)
225}
226
Inseob Kim8697fc82024-04-16 14:45:32 +0900227func (c *policyConf) boardApiLevel(ctx android.ModuleContext) string {
Vadim Caen1d81f872024-08-19 15:08:35 +0200228 return ctx.Config().VendorApiLevel()
Inseob Kim8697fc82024-04-16 14:45:32 +0900229}
230
Inseob Kim0a707fa2021-12-09 23:35:11 +0900231func findPolicyConfOrder(name string) int {
232 for idx, pattern := range policyConfOrder {
Inseob Kim1e796342022-06-09 11:26:35 +0900233 // We could use regexp but it seems like an overkill
234 if pattern == "attributes|*.te" && (name == "attributes" || strings.HasSuffix(name, ".te")) {
235 return idx
236 } else if pattern == name {
Inseob Kim0a707fa2021-12-09 23:35:11 +0900237 return idx
238 }
239 }
240 // name is not matched
241 return len(policyConfOrder)
242}
243
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900244func (c *policyConf) transformPolicyToConf(ctx android.ModuleContext) android.OutputPath {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900245 conf := pathForModuleOut(ctx, c.stem())
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900246 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim0a707fa2021-12-09 23:35:11 +0900247
248 srcs := android.PathsForModuleSrc(ctx, c.properties.Srcs)
249 sort.SliceStable(srcs, func(x, y int) bool {
250 return findPolicyConfOrder(srcs[x].Base()) < findPolicyConfOrder(srcs[y].Base())
251 })
252
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900253 flags := c.getBuildFlags(ctx)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900254 rule.Command().Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
255 Flag("--fatal-warnings").
256 FlagForEachArg("-D ", ctx.DeviceConfig().SepolicyM4Defs()).
257 FlagWithArg("-D mls_num_sens=", strconv.Itoa(MlsSens)).
Inseob Kim6e384f32022-03-10 13:15:05 +0900258 FlagWithArg("-D mls_num_cats=", strconv.Itoa(c.mlsCats())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900259 FlagWithArg("-D target_arch=", ctx.DeviceConfig().DeviceArch()).
260 FlagWithArg("-D target_with_asan=", c.withAsan(ctx)).
Inseob Kim4360c192021-03-23 20:52:53 +0900261 FlagWithArg("-D target_with_dexpreopt=", strconv.FormatBool(ctx.DeviceConfig().WithDexpreopt())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900262 FlagWithArg("-D target_with_native_coverage=", strconv.FormatBool(ctx.DeviceConfig().ClangCoverageEnabled() || ctx.DeviceConfig().GcovCoverageEnabled())).
263 FlagWithArg("-D target_build_variant=", c.buildVariant(ctx)).
264 FlagWithArg("-D target_full_treble=", c.sepolicySplit(ctx)).
265 FlagWithArg("-D target_compatible_property=", c.compatibleProperty(ctx)).
266 FlagWithArg("-D target_treble_sysprop_neverallow=", c.trebleSyspropNeverallow(ctx)).
267 FlagWithArg("-D target_enforce_sysprop_owner=", c.enforceSyspropOwner(ctx)).
268 FlagWithArg("-D target_exclude_build_test=", strconv.FormatBool(proptools.Bool(c.properties.Exclude_build_test))).
269 FlagWithArg("-D target_requires_insecure_execmem_for_swiftshader=", strconv.FormatBool(ctx.DeviceConfig().RequiresInsecureExecmemForSwiftshader())).
Hridya Valsarajua885dd82021-04-26 16:32:17 -0700270 FlagWithArg("-D target_enforce_debugfs_restriction=", c.enforceDebugfsRestrictions(ctx)).
Inseob Kim5bbcd682021-12-28 14:57:03 +0900271 FlagWithArg("-D target_recovery=", strconv.FormatBool(c.isTargetRecovery())).
Inseob Kim8697fc82024-04-16 14:45:32 +0900272 FlagWithArg("-D target_board_api_level=", c.boardApiLevel(ctx)).
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900273 Flags(flagsToM4Macros(flags)).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900274 Flag("-s").
Inseob Kim0a707fa2021-12-09 23:35:11 +0900275 Inputs(srcs).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900276 Text("> ").Output(conf)
277
278 rule.Build("conf", "Transform policy to conf: "+ctx.ModuleName())
279 return conf
280}
281
Inseob Kimbf7f4a42024-02-14 13:53:39 +0900282func (c *policyConf) DepsMutator(ctx android.BottomUpMutatorContext) {
283 c.flagDeps(ctx)
284}
285
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900286func (c *policyConf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900287 if !c.installable() {
288 c.SkipInstall()
289 }
Inseob Kim31db2742021-06-08 10:31:09 +0900290
291 c.installSource = c.transformPolicyToConf(ctx)
292 c.installPath = android.PathForModuleInstall(ctx, "etc")
293 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
mrziwangcb3f5502024-06-06 10:04:23 -0700294
295 ctx.SetOutputFiles(android.Paths{c.installSource}, "")
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900296}
297
298func (c *policyConf) AndroidMkEntries() []android.AndroidMkEntries {
299 return []android.AndroidMkEntries{android.AndroidMkEntries{
300 OutputFile: android.OptionalPathForPath(c.installSource),
301 Class: "ETC",
302 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
303 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
304 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800305 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900306 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
307 },
308 },
309 }}
310}
311
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900312type policyCilProperties struct {
313 // Name of the output. Default is {module_name}
314 Stem *string
315
316 // Policy file to be compiled to cil file.
317 Src *string `android:"path"`
318
Sandro143988d2022-08-05 11:38:56 +0000319 // If true, the input policy file is a binary policy that will be decompiled to a cil file.
320 // Defaults to false.
321 Decompile_binary *bool
322
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900323 // Additional cil files to be added in the end of the output. This is to support workarounds
324 // which are not supported by the policy language.
325 Additional_cil_files []string `android:"path"`
326
327 // Cil files to be filtered out by the filter_out tool of "build_sepolicy". Used to build
328 // exported policies
329 Filter_out []string `android:"path"`
330
331 // Whether to remove line markers (denoted by ;;) out of compiled cil files. Defaults to false
332 Remove_line_marker *bool
333
334 // Whether to run secilc to check compiled policy or not. Defaults to true
335 Secilc_check *bool
336
337 // Whether to ignore neverallow when running secilc check. Defaults to
338 // SELINUX_IGNORE_NEVERALLOWS.
339 Ignore_neverallow *bool
340
341 // Whether this module is directly installable to one of the partitions. Default is true
342 Installable *bool
343}
344
345type policyCil struct {
346 android.ModuleBase
347
348 properties policyCilProperties
349
350 installSource android.Path
351 installPath android.InstallPath
352}
353
354// se_policy_cil compiles a policy.conf file to a cil file with checkpolicy, and optionally runs
355// secilc to check the output cil file. Affected by SELINUX_IGNORE_NEVERALLOWS.
356func policyCilFactory() android.Module {
357 c := &policyCil{}
358 c.AddProperties(&c.properties)
359 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
360 return c
361}
362
363func (c *policyCil) Installable() bool {
364 return proptools.BoolDefault(c.properties.Installable, true)
365}
366
367func (c *policyCil) stem() string {
368 return proptools.StringDefault(c.properties.Stem, c.Name())
369}
370
371func (c *policyCil) compileConfToCil(ctx android.ModuleContext, conf android.Path) android.OutputPath {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900372 cil := pathForModuleOut(ctx, c.stem())
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900373 rule := android.NewRuleBuilder(pctx, ctx)
Sandro143988d2022-08-05 11:38:56 +0000374 checkpolicyCmd := rule.Command().BuiltTool("checkpolicy").
Lokesh Gidra1269a172022-08-01 17:20:38 +0000375 Flag("-C"). // Write CIL
376 Flag("-M"). // Enable MLS
377 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
378 FlagWithOutput("-o ", cil).
379 Input(conf)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900380
Sandro143988d2022-08-05 11:38:56 +0000381 if proptools.Bool(c.properties.Decompile_binary) {
382 checkpolicyCmd.Flag("-b") // Read binary
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900383 }
384
385 if len(c.properties.Filter_out) > 0 {
386 rule.Command().BuiltTool("build_sepolicy").
387 Text("filter_out").
388 Flag("-f").
389 Inputs(android.PathsForModuleSrc(ctx, c.properties.Filter_out)).
390 FlagWithOutput("-t ", cil)
391 }
392
Sandro143988d2022-08-05 11:38:56 +0000393 if len(c.properties.Additional_cil_files) > 0 {
394 rule.Command().Text("cat").
395 Inputs(android.PathsForModuleSrc(ctx, c.properties.Additional_cil_files)).
396 Text(">> ").Output(cil)
397 }
398
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900399 if proptools.Bool(c.properties.Remove_line_marker) {
400 rule.Command().Text("grep -v").
401 Text(proptools.ShellEscape(";;")).
402 Text(cil.String()).
403 Text(">").
404 Text(cil.String() + ".tmp").
405 Text("&& mv").
406 Text(cil.String() + ".tmp").
407 Text(cil.String())
408 }
409
410 if proptools.BoolDefault(c.properties.Secilc_check, true) {
411 secilcCmd := rule.Command().BuiltTool("secilc").
412 Flag("-m"). // Multiple decls
413 FlagWithArg("-M ", "true"). // Enable MLS
414 Flag("-G"). // expand and remove auto generated attributes
415 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
416 Inputs(android.PathsForModuleSrc(ctx, c.properties.Filter_out)). // Also add cil files which are filtered out
417 Text(cil.String()).
418 FlagWithArg("-o ", os.DevNull).
419 FlagWithArg("-f ", os.DevNull)
420
421 if proptools.BoolDefault(c.properties.Ignore_neverallow, ctx.Config().SelinuxIgnoreNeverallows()) {
422 secilcCmd.Flag("-N")
423 }
424 }
425
426 rule.Build("cil", "Building cil for "+ctx.ModuleName())
427 return cil
428}
429
430func (c *policyCil) GenerateAndroidBuildActions(ctx android.ModuleContext) {
431 if proptools.String(c.properties.Src) == "" {
432 ctx.PropertyErrorf("src", "must be specified")
433 return
434 }
435 conf := android.PathForModuleSrc(ctx, *c.properties.Src)
436 cil := c.compileConfToCil(ctx, conf)
437
Inseob Kim31db2742021-06-08 10:31:09 +0900438 if !c.Installable() {
439 c.SkipInstall()
440 }
441
Inseob Kim6cc75f42021-04-29 13:53:20 +0000442 if c.InstallInDebugRamdisk() {
443 // for userdebug_plat_sepolicy.cil
444 c.installPath = android.PathForModuleInstall(ctx)
445 } else {
446 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
447 }
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900448 c.installSource = cil
449 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
mrziwangcb3f5502024-06-06 10:04:23 -0700450
451 ctx.SetOutputFiles(android.Paths{c.installSource}, "")
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900452}
453
454func (c *policyCil) AndroidMkEntries() []android.AndroidMkEntries {
455 return []android.AndroidMkEntries{android.AndroidMkEntries{
456 OutputFile: android.OptionalPathForPath(c.installSource),
457 Class: "ETC",
458 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
459 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
460 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.Installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800461 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900462 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
463 },
464 },
465 }}
466}
467
Inseob Kimb9d05112021-09-27 13:13:46 +0000468type policyBinaryProperties struct {
469 // Name of the output. Default is {module_name}
470 Stem *string
471
472 // Cil files to be compiled.
473 Srcs []string `android:"path"`
474
475 // Whether to ignore neverallow when running secilc check. Defaults to
476 // SELINUX_IGNORE_NEVERALLOWS.
477 Ignore_neverallow *bool
478
479 // Whether this module is directly installable to one of the partitions. Default is true
480 Installable *bool
Jiyong Parkef567212022-12-05 14:06:47 +0900481
482 // List of domains that are allowed to be in permissive mode on user builds.
483 Permissive_domains_on_user_builds []string
Inseob Kimb9d05112021-09-27 13:13:46 +0000484}
485
486type policyBinary struct {
487 android.ModuleBase
488
489 properties policyBinaryProperties
490
491 installSource android.Path
492 installPath android.InstallPath
493}
494
495// se_policy_binary compiles cil files to a binary sepolicy file with secilc. Usually sources of
496// se_policy_binary come from outputs of se_policy_cil modules.
497func policyBinaryFactory() android.Module {
498 c := &policyBinary{}
499 c.AddProperties(&c.properties)
500 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
501 return c
502}
503
Inseob Kim5bbcd682021-12-28 14:57:03 +0900504func (c *policyBinary) InstallInRoot() bool {
505 return c.InstallInRecovery()
506}
507
Inseob Kimb9d05112021-09-27 13:13:46 +0000508func (c *policyBinary) Installable() bool {
509 return proptools.BoolDefault(c.properties.Installable, true)
510}
511
512func (c *policyBinary) stem() string {
513 return proptools.StringDefault(c.properties.Stem, c.Name())
514}
515
516func (c *policyBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
517 if len(c.properties.Srcs) == 0 {
518 ctx.PropertyErrorf("srcs", "must be specified")
519 return
520 }
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900521 bin := pathForModuleOut(ctx, c.stem()+"_policy")
Inseob Kimb9d05112021-09-27 13:13:46 +0000522 rule := android.NewRuleBuilder(pctx, ctx)
523 secilcCmd := rule.Command().BuiltTool("secilc").
524 Flag("-m"). // Multiple decls
525 FlagWithArg("-M ", "true"). // Enable MLS
526 Flag("-G"). // expand and remove auto generated attributes
527 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
528 Inputs(android.PathsForModuleSrc(ctx, c.properties.Srcs)).
529 FlagWithOutput("-o ", bin).
530 FlagWithArg("-f ", os.DevNull)
531
532 if proptools.BoolDefault(c.properties.Ignore_neverallow, ctx.Config().SelinuxIgnoreNeverallows()) {
533 secilcCmd.Flag("-N")
534 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900535 rule.Temporary(bin)
Inseob Kimb9d05112021-09-27 13:13:46 +0000536
Inseob Kim3d5f9252021-12-21 20:42:35 +0900537 // permissive check is performed only in user build (not debuggable).
538 if !ctx.Config().Debuggable() {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900539 permissiveDomains := pathForModuleOut(ctx, c.stem()+"_permissive")
Jiyong Parkef567212022-12-05 14:06:47 +0900540 cmd := rule.Command().BuiltTool("sepolicy-analyze").
Inseob Kim3d5f9252021-12-21 20:42:35 +0900541 Input(bin).
Jiyong Parkef567212022-12-05 14:06:47 +0900542 Text("permissive")
543 // Filter-out domains listed in permissive_domains_on_user_builds
544 allowedDomains := c.properties.Permissive_domains_on_user_builds
545 if len(allowedDomains) != 0 {
546 cmd.Text("| { grep -Fxv")
547 for _, d := range allowedDomains {
548 cmd.FlagWithArg("-e ", proptools.ShellEscape(d))
549 }
550 cmd.Text(" || true; }") // no match doesn't fail the cmd
551 }
552 cmd.Text(" > ").Output(permissiveDomains)
Inseob Kim3d5f9252021-12-21 20:42:35 +0900553 rule.Temporary(permissiveDomains)
554
555 msg := `==========\n` +
556 `ERROR: permissive domains not allowed in user builds\n` +
557 `List of invalid domains:`
558
559 rule.Command().Text("if test").
560 FlagWithInput("-s ", permissiveDomains).
561 Text("; then echo").
562 Flag("-e").
563 Text(`"` + msg + `"`).
564 Text("&& cat ").
565 Input(permissiveDomains).
566 Text("; exit 1; fi")
567 }
568
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900569 out := pathForModuleOut(ctx, c.stem())
Inseob Kim3d5f9252021-12-21 20:42:35 +0900570 rule.Command().Text("cp").
571 Flag("-f").
572 Input(bin).
573 Output(out)
574
575 rule.DeleteTemporaryFiles()
Inseob Kimb9d05112021-09-27 13:13:46 +0000576 rule.Build("secilc", "Compiling cil files for "+ctx.ModuleName())
577
578 if !c.Installable() {
579 c.SkipInstall()
580 }
581
Inseob Kim5bbcd682021-12-28 14:57:03 +0900582 if c.InstallInRecovery() {
583 // install in root
584 c.installPath = android.PathForModuleInstall(ctx)
585 } else {
586 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
587 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900588 c.installSource = out
Inseob Kimb9d05112021-09-27 13:13:46 +0000589 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
mrziwangcb3f5502024-06-06 10:04:23 -0700590
591 ctx.SetOutputFiles(android.Paths{c.installSource}, "")
Inseob Kimb9d05112021-09-27 13:13:46 +0000592}
593
594func (c *policyBinary) AndroidMkEntries() []android.AndroidMkEntries {
595 return []android.AndroidMkEntries{android.AndroidMkEntries{
596 OutputFile: android.OptionalPathForPath(c.installSource),
597 Class: "ETC",
598 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
599 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
600 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.Installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800601 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kimb9d05112021-09-27 13:13:46 +0000602 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
603 },
604 },
605 }}
606}