blob: 9d872755060916490d73e7ef155fbcbecb803de0 [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"
Inseob Kim0a707fa2021-12-09 23:35:11 +090020 "sort"
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090021 "strconv"
Inseob Kim0a707fa2021-12-09 23:35:11 +090022 "strings"
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090023
24 "github.com/google/blueprint/proptools"
25
26 "android/soong/android"
27)
28
29const (
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090030 MlsSens = 1
31 MlsCats = 1024
32 PolicyVers = 30
33)
34
Inseob Kim0a707fa2021-12-09 23:35:11 +090035// This order should be kept. checkpolicy syntax requires it.
36var policyConfOrder = []string{
37 "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 Kim7e8bd1e2021-03-17 18:59:43 +090093}
94
95type policyConf struct {
96 android.ModuleBase
Inseob Kim6cd0ddd2023-10-25 23:48:16 +090097 android.DefaultableModuleBase
98 flaggableModuleBase
Inseob Kim7e8bd1e2021-03-17 18:59:43 +090099
100 properties policyConfProperties
101
102 installSource android.Path
103 installPath android.InstallPath
104}
105
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900106var _ flaggableModule = (*policyConf)(nil)
107
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900108// se_policy_conf merges collection of policy files into a policy.conf file to be processed by
109// checkpolicy.
110func policyConfFactory() android.Module {
111 c := &policyConf{}
112 c.AddProperties(&c.properties)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900113 initFlaggableModule(c)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900114 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900115 android.InitDefaultableModule(c)
116 return c
117}
118
119type policyConfDefaults struct {
120 android.ModuleBase
121 android.DefaultsModuleBase
122}
123
124// se_policy_conf_defaults provides a set of properties that can be inherited by other
125// se_policy_conf_defaults modules. A module can use the properties from a se_policy_conf_defaults
126// using `defaults: ["<:default_module_name>"]`. Properties of both modules are merged (when
127// possible) by prepending the default module's values to the depending module's values.
128func policyConfDefaultFactory() android.Module {
129 c := &policyConfDefaults{}
130 c.AddProperties(
131 &policyConfProperties{},
132 &flagsProperties{},
133 )
134 android.InitDefaultsModule(c)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900135 return c
136}
137
138func (c *policyConf) installable() bool {
139 return proptools.BoolDefault(c.properties.Installable, true)
140}
141
142func (c *policyConf) stem() string {
143 return proptools.StringDefault(c.properties.Stem, c.Name())
144}
145
146func (c *policyConf) buildVariant(ctx android.ModuleContext) string {
147 if variant := proptools.String(c.properties.Build_variant); variant != "" {
148 return variant
149 }
150 if ctx.Config().Eng() {
151 return "eng"
152 }
153 if ctx.Config().Debuggable() {
154 return "userdebug"
155 }
156 return "user"
157}
158
159func (c *policyConf) cts() bool {
160 return proptools.Bool(c.properties.Cts)
161}
162
Inseob Kim5bbcd682021-12-28 14:57:03 +0900163func (c *policyConf) isTargetRecovery() bool {
164 return proptools.Bool(c.properties.Target_recovery)
165}
166
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900167func (c *policyConf) withAsan(ctx android.ModuleContext) string {
168 isAsanDevice := android.InList("address", ctx.Config().SanitizeDevice())
169 return strconv.FormatBool(proptools.BoolDefault(c.properties.With_asan, isAsanDevice))
170}
171
172func (c *policyConf) sepolicySplit(ctx android.ModuleContext) string {
173 if c.cts() {
174 return "cts"
175 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900176 if c.isTargetRecovery() {
177 return "false"
178 }
Steven Moreland721f5af2023-05-31 21:54:51 +0000179 return strconv.FormatBool(true)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900180}
181
182func (c *policyConf) compatibleProperty(ctx android.ModuleContext) string {
183 if c.cts() {
184 return "cts"
185 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900186 if c.isTargetRecovery() {
187 return "false"
188 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900189 return "true"
190}
191
192func (c *policyConf) trebleSyspropNeverallow(ctx android.ModuleContext) string {
193 if c.cts() {
194 return "cts"
195 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900196 if c.isTargetRecovery() {
197 return "false"
198 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900199 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenTrebleSyspropNeverallow())
200}
201
202func (c *policyConf) enforceSyspropOwner(ctx android.ModuleContext) string {
203 if c.cts() {
204 return "cts"
205 }
Inseob Kim5bbcd682021-12-28 14:57:03 +0900206 if c.isTargetRecovery() {
207 return "false"
208 }
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900209 return strconv.FormatBool(!ctx.DeviceConfig().BuildBrokenEnforceSyspropOwner())
210}
211
Hridya Valsarajua885dd82021-04-26 16:32:17 -0700212func (c *policyConf) enforceDebugfsRestrictions(ctx android.ModuleContext) string {
213 if c.cts() {
214 return "cts"
215 }
216 return strconv.FormatBool(ctx.DeviceConfig().BuildDebugfsRestrictionsEnabled())
217}
218
Inseob Kim6e384f32022-03-10 13:15:05 +0900219func (c *policyConf) mlsCats() int {
220 return proptools.IntDefault(c.properties.Mls_cats, MlsCats)
221}
222
Inseob Kim0a707fa2021-12-09 23:35:11 +0900223func findPolicyConfOrder(name string) int {
224 for idx, pattern := range policyConfOrder {
Inseob Kim1e796342022-06-09 11:26:35 +0900225 // We could use regexp but it seems like an overkill
226 if pattern == "attributes|*.te" && (name == "attributes" || strings.HasSuffix(name, ".te")) {
227 return idx
228 } else if pattern == name {
Inseob Kim0a707fa2021-12-09 23:35:11 +0900229 return idx
230 }
231 }
232 // name is not matched
233 return len(policyConfOrder)
234}
235
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900236func (c *policyConf) transformPolicyToConf(ctx android.ModuleContext) android.OutputPath {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900237 conf := pathForModuleOut(ctx, c.stem())
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900238 rule := android.NewRuleBuilder(pctx, ctx)
Inseob Kim0a707fa2021-12-09 23:35:11 +0900239
240 srcs := android.PathsForModuleSrc(ctx, c.properties.Srcs)
241 sort.SliceStable(srcs, func(x, y int) bool {
242 return findPolicyConfOrder(srcs[x].Base()) < findPolicyConfOrder(srcs[y].Base())
243 })
244
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900245 flags := c.getBuildFlags(ctx)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900246 rule.Command().Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
247 Flag("--fatal-warnings").
248 FlagForEachArg("-D ", ctx.DeviceConfig().SepolicyM4Defs()).
249 FlagWithArg("-D mls_num_sens=", strconv.Itoa(MlsSens)).
Inseob Kim6e384f32022-03-10 13:15:05 +0900250 FlagWithArg("-D mls_num_cats=", strconv.Itoa(c.mlsCats())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900251 FlagWithArg("-D target_arch=", ctx.DeviceConfig().DeviceArch()).
252 FlagWithArg("-D target_with_asan=", c.withAsan(ctx)).
Inseob Kim4360c192021-03-23 20:52:53 +0900253 FlagWithArg("-D target_with_dexpreopt=", strconv.FormatBool(ctx.DeviceConfig().WithDexpreopt())).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900254 FlagWithArg("-D target_with_native_coverage=", strconv.FormatBool(ctx.DeviceConfig().ClangCoverageEnabled() || ctx.DeviceConfig().GcovCoverageEnabled())).
255 FlagWithArg("-D target_build_variant=", c.buildVariant(ctx)).
256 FlagWithArg("-D target_full_treble=", c.sepolicySplit(ctx)).
257 FlagWithArg("-D target_compatible_property=", c.compatibleProperty(ctx)).
258 FlagWithArg("-D target_treble_sysprop_neverallow=", c.trebleSyspropNeverallow(ctx)).
259 FlagWithArg("-D target_enforce_sysprop_owner=", c.enforceSyspropOwner(ctx)).
260 FlagWithArg("-D target_exclude_build_test=", strconv.FormatBool(proptools.Bool(c.properties.Exclude_build_test))).
261 FlagWithArg("-D target_requires_insecure_execmem_for_swiftshader=", strconv.FormatBool(ctx.DeviceConfig().RequiresInsecureExecmemForSwiftshader())).
Hridya Valsarajua885dd82021-04-26 16:32:17 -0700262 FlagWithArg("-D target_enforce_debugfs_restriction=", c.enforceDebugfsRestrictions(ctx)).
Inseob Kim5bbcd682021-12-28 14:57:03 +0900263 FlagWithArg("-D target_recovery=", strconv.FormatBool(c.isTargetRecovery())).
Inseob Kim6cd0ddd2023-10-25 23:48:16 +0900264 Flags(flagsToM4Macros(flags)).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900265 Flag("-s").
Inseob Kim0a707fa2021-12-09 23:35:11 +0900266 Inputs(srcs).
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900267 Text("> ").Output(conf)
268
269 rule.Build("conf", "Transform policy to conf: "+ctx.ModuleName())
270 return conf
271}
272
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900273func (c *policyConf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900274 if !c.installable() {
275 c.SkipInstall()
276 }
Inseob Kim31db2742021-06-08 10:31:09 +0900277
278 c.installSource = c.transformPolicyToConf(ctx)
279 c.installPath = android.PathForModuleInstall(ctx, "etc")
280 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900281}
282
283func (c *policyConf) AndroidMkEntries() []android.AndroidMkEntries {
284 return []android.AndroidMkEntries{android.AndroidMkEntries{
285 OutputFile: android.OptionalPathForPath(c.installSource),
286 Class: "ETC",
287 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
288 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
289 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800290 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kim7e8bd1e2021-03-17 18:59:43 +0900291 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
292 },
293 },
294 }}
295}
296
297func (c *policyConf) OutputFiles(tag string) (android.Paths, error) {
298 if tag == "" {
299 return android.Paths{c.installSource}, nil
300 }
301 return nil, fmt.Errorf("Unknown tag %q", tag)
302}
303
304var _ android.OutputFileProducer = (*policyConf)(nil)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900305
306type policyCilProperties struct {
307 // Name of the output. Default is {module_name}
308 Stem *string
309
310 // Policy file to be compiled to cil file.
311 Src *string `android:"path"`
312
Sandro143988d2022-08-05 11:38:56 +0000313 // If true, the input policy file is a binary policy that will be decompiled to a cil file.
314 // Defaults to false.
315 Decompile_binary *bool
316
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900317 // Additional cil files to be added in the end of the output. This is to support workarounds
318 // which are not supported by the policy language.
319 Additional_cil_files []string `android:"path"`
320
321 // Cil files to be filtered out by the filter_out tool of "build_sepolicy". Used to build
322 // exported policies
323 Filter_out []string `android:"path"`
324
325 // Whether to remove line markers (denoted by ;;) out of compiled cil files. Defaults to false
326 Remove_line_marker *bool
327
328 // Whether to run secilc to check compiled policy or not. Defaults to true
329 Secilc_check *bool
330
331 // Whether to ignore neverallow when running secilc check. Defaults to
332 // SELINUX_IGNORE_NEVERALLOWS.
333 Ignore_neverallow *bool
334
335 // Whether this module is directly installable to one of the partitions. Default is true
336 Installable *bool
337}
338
339type policyCil struct {
340 android.ModuleBase
341
342 properties policyCilProperties
343
344 installSource android.Path
345 installPath android.InstallPath
346}
347
348// se_policy_cil compiles a policy.conf file to a cil file with checkpolicy, and optionally runs
349// secilc to check the output cil file. Affected by SELINUX_IGNORE_NEVERALLOWS.
350func policyCilFactory() android.Module {
351 c := &policyCil{}
352 c.AddProperties(&c.properties)
353 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
354 return c
355}
356
357func (c *policyCil) Installable() bool {
358 return proptools.BoolDefault(c.properties.Installable, true)
359}
360
361func (c *policyCil) stem() string {
362 return proptools.StringDefault(c.properties.Stem, c.Name())
363}
364
365func (c *policyCil) compileConfToCil(ctx android.ModuleContext, conf android.Path) android.OutputPath {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900366 cil := pathForModuleOut(ctx, c.stem())
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900367 rule := android.NewRuleBuilder(pctx, ctx)
Sandro143988d2022-08-05 11:38:56 +0000368 checkpolicyCmd := rule.Command().BuiltTool("checkpolicy").
Lokesh Gidra1269a172022-08-01 17:20:38 +0000369 Flag("-C"). // Write CIL
370 Flag("-M"). // Enable MLS
371 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
372 FlagWithOutput("-o ", cil).
373 Input(conf)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900374
Sandro143988d2022-08-05 11:38:56 +0000375 if proptools.Bool(c.properties.Decompile_binary) {
376 checkpolicyCmd.Flag("-b") // Read binary
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900377 }
378
379 if len(c.properties.Filter_out) > 0 {
380 rule.Command().BuiltTool("build_sepolicy").
381 Text("filter_out").
382 Flag("-f").
383 Inputs(android.PathsForModuleSrc(ctx, c.properties.Filter_out)).
384 FlagWithOutput("-t ", cil)
385 }
386
Sandro143988d2022-08-05 11:38:56 +0000387 if len(c.properties.Additional_cil_files) > 0 {
388 rule.Command().Text("cat").
389 Inputs(android.PathsForModuleSrc(ctx, c.properties.Additional_cil_files)).
390 Text(">> ").Output(cil)
391 }
392
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900393 if proptools.Bool(c.properties.Remove_line_marker) {
394 rule.Command().Text("grep -v").
395 Text(proptools.ShellEscape(";;")).
396 Text(cil.String()).
397 Text(">").
398 Text(cil.String() + ".tmp").
399 Text("&& mv").
400 Text(cil.String() + ".tmp").
401 Text(cil.String())
402 }
403
404 if proptools.BoolDefault(c.properties.Secilc_check, true) {
405 secilcCmd := rule.Command().BuiltTool("secilc").
406 Flag("-m"). // Multiple decls
407 FlagWithArg("-M ", "true"). // Enable MLS
408 Flag("-G"). // expand and remove auto generated attributes
409 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
410 Inputs(android.PathsForModuleSrc(ctx, c.properties.Filter_out)). // Also add cil files which are filtered out
411 Text(cil.String()).
412 FlagWithArg("-o ", os.DevNull).
413 FlagWithArg("-f ", os.DevNull)
414
415 if proptools.BoolDefault(c.properties.Ignore_neverallow, ctx.Config().SelinuxIgnoreNeverallows()) {
416 secilcCmd.Flag("-N")
417 }
418 }
419
420 rule.Build("cil", "Building cil for "+ctx.ModuleName())
421 return cil
422}
423
424func (c *policyCil) GenerateAndroidBuildActions(ctx android.ModuleContext) {
425 if proptools.String(c.properties.Src) == "" {
426 ctx.PropertyErrorf("src", "must be specified")
427 return
428 }
429 conf := android.PathForModuleSrc(ctx, *c.properties.Src)
430 cil := c.compileConfToCil(ctx, conf)
431
Inseob Kim31db2742021-06-08 10:31:09 +0900432 if !c.Installable() {
433 c.SkipInstall()
434 }
435
Inseob Kim6cc75f42021-04-29 13:53:20 +0000436 if c.InstallInDebugRamdisk() {
437 // for userdebug_plat_sepolicy.cil
438 c.installPath = android.PathForModuleInstall(ctx)
439 } else {
440 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
441 }
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900442 c.installSource = cil
443 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900444}
445
446func (c *policyCil) AndroidMkEntries() []android.AndroidMkEntries {
447 return []android.AndroidMkEntries{android.AndroidMkEntries{
448 OutputFile: android.OptionalPathForPath(c.installSource),
449 Class: "ETC",
450 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
451 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
452 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.Installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800453 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kimdf1a0de2021-03-17 19:05:02 +0900454 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
455 },
456 },
457 }}
458}
459
460func (c *policyCil) OutputFiles(tag string) (android.Paths, error) {
461 if tag == "" {
462 return android.Paths{c.installSource}, nil
463 }
464 return nil, fmt.Errorf("Unknown tag %q", tag)
465}
466
467var _ android.OutputFileProducer = (*policyCil)(nil)
Inseob Kimb9d05112021-09-27 13:13:46 +0000468
469type policyBinaryProperties struct {
470 // Name of the output. Default is {module_name}
471 Stem *string
472
473 // Cil files to be compiled.
474 Srcs []string `android:"path"`
475
476 // Whether to ignore neverallow when running secilc check. Defaults to
477 // SELINUX_IGNORE_NEVERALLOWS.
478 Ignore_neverallow *bool
479
480 // Whether this module is directly installable to one of the partitions. Default is true
481 Installable *bool
Jiyong Parkef567212022-12-05 14:06:47 +0900482
483 // List of domains that are allowed to be in permissive mode on user builds.
484 Permissive_domains_on_user_builds []string
Inseob Kimb9d05112021-09-27 13:13:46 +0000485}
486
487type policyBinary struct {
488 android.ModuleBase
489
490 properties policyBinaryProperties
491
492 installSource android.Path
493 installPath android.InstallPath
494}
495
496// se_policy_binary compiles cil files to a binary sepolicy file with secilc. Usually sources of
497// se_policy_binary come from outputs of se_policy_cil modules.
498func policyBinaryFactory() android.Module {
499 c := &policyBinary{}
500 c.AddProperties(&c.properties)
501 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
502 return c
503}
504
Inseob Kim5bbcd682021-12-28 14:57:03 +0900505func (c *policyBinary) InstallInRoot() bool {
506 return c.InstallInRecovery()
507}
508
Inseob Kimb9d05112021-09-27 13:13:46 +0000509func (c *policyBinary) Installable() bool {
510 return proptools.BoolDefault(c.properties.Installable, true)
511}
512
513func (c *policyBinary) stem() string {
514 return proptools.StringDefault(c.properties.Stem, c.Name())
515}
516
517func (c *policyBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
518 if len(c.properties.Srcs) == 0 {
519 ctx.PropertyErrorf("srcs", "must be specified")
520 return
521 }
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900522 bin := pathForModuleOut(ctx, c.stem()+"_policy")
Inseob Kimb9d05112021-09-27 13:13:46 +0000523 rule := android.NewRuleBuilder(pctx, ctx)
524 secilcCmd := rule.Command().BuiltTool("secilc").
525 Flag("-m"). // Multiple decls
526 FlagWithArg("-M ", "true"). // Enable MLS
527 Flag("-G"). // expand and remove auto generated attributes
528 FlagWithArg("-c ", strconv.Itoa(PolicyVers)).
529 Inputs(android.PathsForModuleSrc(ctx, c.properties.Srcs)).
530 FlagWithOutput("-o ", bin).
531 FlagWithArg("-f ", os.DevNull)
532
533 if proptools.BoolDefault(c.properties.Ignore_neverallow, ctx.Config().SelinuxIgnoreNeverallows()) {
534 secilcCmd.Flag("-N")
535 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900536 rule.Temporary(bin)
Inseob Kimb9d05112021-09-27 13:13:46 +0000537
Inseob Kim3d5f9252021-12-21 20:42:35 +0900538 // permissive check is performed only in user build (not debuggable).
539 if !ctx.Config().Debuggable() {
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900540 permissiveDomains := pathForModuleOut(ctx, c.stem()+"_permissive")
Jiyong Parkef567212022-12-05 14:06:47 +0900541 cmd := rule.Command().BuiltTool("sepolicy-analyze").
Inseob Kim3d5f9252021-12-21 20:42:35 +0900542 Input(bin).
Jiyong Parkef567212022-12-05 14:06:47 +0900543 Text("permissive")
544 // Filter-out domains listed in permissive_domains_on_user_builds
545 allowedDomains := c.properties.Permissive_domains_on_user_builds
546 if len(allowedDomains) != 0 {
547 cmd.Text("| { grep -Fxv")
548 for _, d := range allowedDomains {
549 cmd.FlagWithArg("-e ", proptools.ShellEscape(d))
550 }
551 cmd.Text(" || true; }") // no match doesn't fail the cmd
552 }
553 cmd.Text(" > ").Output(permissiveDomains)
Inseob Kim3d5f9252021-12-21 20:42:35 +0900554 rule.Temporary(permissiveDomains)
555
556 msg := `==========\n` +
557 `ERROR: permissive domains not allowed in user builds\n` +
558 `List of invalid domains:`
559
560 rule.Command().Text("if test").
561 FlagWithInput("-s ", permissiveDomains).
562 Text("; then echo").
563 Flag("-e").
564 Text(`"` + msg + `"`).
565 Text("&& cat ").
566 Input(permissiveDomains).
567 Text("; exit 1; fi")
568 }
569
Inseob Kim6c6f53b2023-04-26 11:03:35 +0900570 out := pathForModuleOut(ctx, c.stem())
Inseob Kim3d5f9252021-12-21 20:42:35 +0900571 rule.Command().Text("cp").
572 Flag("-f").
573 Input(bin).
574 Output(out)
575
576 rule.DeleteTemporaryFiles()
Inseob Kimb9d05112021-09-27 13:13:46 +0000577 rule.Build("secilc", "Compiling cil files for "+ctx.ModuleName())
578
579 if !c.Installable() {
580 c.SkipInstall()
581 }
582
Inseob Kim5bbcd682021-12-28 14:57:03 +0900583 if c.InstallInRecovery() {
584 // install in root
585 c.installPath = android.PathForModuleInstall(ctx)
586 } else {
587 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
588 }
Inseob Kim3d5f9252021-12-21 20:42:35 +0900589 c.installSource = out
Inseob Kimb9d05112021-09-27 13:13:46 +0000590 ctx.InstallFile(c.installPath, c.stem(), c.installSource)
591}
592
593func (c *policyBinary) AndroidMkEntries() []android.AndroidMkEntries {
594 return []android.AndroidMkEntries{android.AndroidMkEntries{
595 OutputFile: android.OptionalPathForPath(c.installSource),
596 Class: "ETC",
597 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
598 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
599 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !c.Installable())
Colin Cross6c7f9372022-01-11 19:35:43 -0800600 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Inseob Kimb9d05112021-09-27 13:13:46 +0000601 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
602 },
603 },
604 }}
605}
606
607func (c *policyBinary) OutputFiles(tag string) (android.Paths, error) {
608 if tag == "" {
609 return android.Paths{c.installSource}, nil
610 }
611 return nil, fmt.Errorf("Unknown tag %q", tag)
612}
613
614var _ android.OutputFileProducer = (*policyBinary)(nil)