blob: 33c6d3b61452ad5af6f963771b693d3499d4cb59 [file] [log] [blame]
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +08001// Copyright 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 Kim16d3be32022-01-07 09:15:27 +090018 "fmt"
19
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080020 "github.com/google/blueprint/proptools"
21
22 "android/soong/android"
23)
24
Inseob Kim16d3be32022-01-07 09:15:27 +090025var (
26 compatTestDepTag = dependencyTag{name: "compat_test"}
27)
28
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080029func init() {
Inseob Kim16d3be32022-01-07 09:15:27 +090030 ctx := android.InitRegistrationContext
31 ctx.RegisterModuleType("se_compat_cil", compatCilFactory)
Cole Faust8fe65682024-11-04 16:31:39 -080032 ctx.RegisterModuleType("se_compat_test", compatTestFactory)
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080033}
34
35// se_compat_cil collects and installs backwards compatibility cil files.
36func compatCilFactory() android.Module {
37 c := &compatCil{}
38 c.AddProperties(&c.properties)
39 android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
40 return c
41}
42
43type compatCil struct {
44 android.ModuleBase
45 properties compatCilProperties
Inseob Kim61d6beb2023-08-23 08:37:20 +000046 installSource android.OptionalPath
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080047 installPath android.InstallPath
48}
49
50type compatCilProperties struct {
Inseob Kim41964032022-04-22 07:50:22 +090051 // List of source files. Can reference se_build_files type modules with the ":module" syntax.
Paul Duffin532bde12021-07-09 22:53:03 +010052 Srcs []string `android:"path"`
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080053
54 // Output file name. Defaults to module name if unspecified.
55 Stem *string
Inseob Kim61d6beb2023-08-23 08:37:20 +000056
57 // Target version that this module supports. This module will be ignored if platform sepolicy
58 // version is same as this module's version.
59 Version *string
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080060}
61
62func (c *compatCil) stem() string {
63 return proptools.StringDefault(c.properties.Stem, c.Name())
64}
65
66func (c *compatCil) expandSeSources(ctx android.ModuleContext) android.Paths {
Inseob Kim41964032022-04-22 07:50:22 +090067 return android.PathsForModuleSrc(ctx, c.properties.Srcs)
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080068}
69
Inseob Kim61d6beb2023-08-23 08:37:20 +000070func (c *compatCil) shouldSkipBuild(ctx android.ModuleContext) bool {
71 return proptools.String(c.properties.Version) == ctx.DeviceConfig().PlatformSepolicyVersion()
72}
73
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080074func (c *compatCil) GenerateAndroidBuildActions(ctx android.ModuleContext) {
75 if c.ProductSpecific() || c.SocSpecific() || c.DeviceSpecific() {
76 ctx.ModuleErrorf("Compat cil files only support system and system_ext partitions")
77 }
78
Inseob Kim61d6beb2023-08-23 08:37:20 +000079 if c.shouldSkipBuild(ctx) {
80 return
81 }
82
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080083 srcPaths := c.expandSeSources(ctx)
84 out := android.PathForModuleGen(ctx, c.Name())
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080085 ctx.Build(pctx, android.BuildParams{
86 Rule: android.Cat,
87 Inputs: srcPaths,
88 Output: out,
89 Description: "Combining compat cil for " + c.Name(),
90 })
91
92 c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux", "mapping")
Inseob Kim61d6beb2023-08-23 08:37:20 +000093 c.installSource = android.OptionalPathForPath(out)
94 ctx.InstallFile(c.installPath, c.stem(), out)
mrziwangcb3f5502024-06-06 10:04:23 -070095
96 if c.installSource.Valid() {
97 ctx.SetOutputFiles(android.Paths{c.installSource.Path()}, "")
98 }
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +080099}
100
101func (c *compatCil) AndroidMkEntries() []android.AndroidMkEntries {
Inseob Kim61d6beb2023-08-23 08:37:20 +0000102 if !c.installSource.Valid() {
103 return nil
104 }
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +0800105 return []android.AndroidMkEntries{android.AndroidMkEntries{
106 Class: "ETC",
Inseob Kim61d6beb2023-08-23 08:37:20 +0000107 OutputFile: c.installSource,
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +0800108 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
109 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
Colin Cross6c7f9372022-01-11 19:35:43 -0800110 entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
Yi-Yo Chiang41c34d62021-04-13 02:44:41 +0800111 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
112 },
113 },
114 }}
115}
Inseob Kim16d3be32022-01-07 09:15:27 +0900116
Inseob Kim16d3be32022-01-07 09:15:27 +0900117// se_compat_test checks if compat files ({ver}.cil, {ver}.compat.cil) files are compatible with
118// current policy.
Cole Faust8fe65682024-11-04 16:31:39 -0800119func compatTestFactory() android.Module {
Inseob Kim16d3be32022-01-07 09:15:27 +0900120 f := &compatTestModule{}
Inseob Kim085f22f2023-11-09 11:13:01 +0900121 f.AddProperties(&f.properties)
Cole Faust09e326f2024-10-07 16:54:31 -0700122 android.InitAndroidArchModule(f, android.DeviceSupported, android.MultilibCommon)
Inseob Kim16d3be32022-01-07 09:15:27 +0900123 android.AddLoadHook(f, func(ctx android.LoadHookContext) {
124 f.loadHook(ctx)
125 })
126 return f
127}
128
129type compatTestModule struct {
Cole Faust8fe65682024-11-04 16:31:39 -0800130 android.ModuleBase
Inseob Kim085f22f2023-11-09 11:13:01 +0900131 properties struct {
132 // Default modules for conf
133 Defaults []string
134 }
Inseob Kim16d3be32022-01-07 09:15:27 +0900135
136 compatTestTimestamp android.ModuleOutPath
137}
138
Inseob Kim16d3be32022-01-07 09:15:27 +0900139func (f *compatTestModule) createCompatTestModule(ctx android.LoadHookContext, ver string) {
140 srcs := []string{
141 ":plat_sepolicy.cil",
142 ":system_ext_sepolicy.cil",
143 ":product_sepolicy.cil",
144 fmt.Sprintf(":plat_%s.cil", ver),
145 fmt.Sprintf(":%s.compat.cil", ver),
146 fmt.Sprintf(":system_ext_%s.cil", ver),
147 fmt.Sprintf(":system_ext_%s.compat.cil", ver),
148 fmt.Sprintf(":product_%s.cil", ver),
149 }
150
151 if ver == ctx.DeviceConfig().BoardSepolicyVers() {
152 srcs = append(srcs,
153 ":plat_pub_versioned.cil",
154 ":vendor_sepolicy.cil",
155 ":odm_sepolicy.cil",
156 )
157 } else {
Inseob Kim10f04502024-07-18 10:26:43 +0900158 srcs = append(srcs, fmt.Sprintf(":%s_plat_pub_versioned.cil", ver))
Inseob Kim16d3be32022-01-07 09:15:27 +0900159 }
160
161 compatTestName := fmt.Sprintf("%s_compat_test", ver)
162 ctx.CreateModule(policyBinaryFactory, &nameProperties{
163 Name: proptools.StringPtr(compatTestName),
164 }, &policyBinaryProperties{
165 Srcs: srcs,
166 Ignore_neverallow: proptools.BoolPtr(true),
167 Installable: proptools.BoolPtr(false),
168 })
169}
170
171func (f *compatTestModule) loadHook(ctx android.LoadHookContext) {
172 for _, ver := range ctx.DeviceConfig().PlatformSepolicyCompatVersions() {
Inseob Kim16d3be32022-01-07 09:15:27 +0900173 f.createCompatTestModule(ctx, ver)
174 }
175}
176
177func (f *compatTestModule) DepsMutator(ctx android.BottomUpMutatorContext) {
178 for _, ver := range ctx.DeviceConfig().PlatformSepolicyCompatVersions() {
179 ctx.AddDependency(f, compatTestDepTag, fmt.Sprintf("%s_compat_test", ver))
180 }
181}
182
Inseob Kim16d3be32022-01-07 09:15:27 +0900183func (f *compatTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Cole Faust8fe65682024-11-04 16:31:39 -0800184 if ctx.ModuleName() != "sepolicy_compat_test" || ctx.ModuleDir() != "system/sepolicy/compat" {
185 // two compat test modules don't make sense.
186 ctx.ModuleErrorf("There can only be 1 se_compat_test module named sepolicy_compat_test in system/sepolicy/compat")
187 }
Inseob Kim16d3be32022-01-07 09:15:27 +0900188 var inputs android.Paths
189 ctx.VisitDirectDepsWithTag(compatTestDepTag, func(child android.Module) {
mrziwangcb3f5502024-06-06 10:04:23 -0700190 outputs := android.OutputFilesForModule(ctx, child, "")
Inseob Kim16d3be32022-01-07 09:15:27 +0900191 if len(outputs) != 1 {
192 panic(fmt.Errorf("Module %q should produce exactly one output, but did %q", ctx.OtherModuleName(child), outputs.Strings()))
193 }
194
195 inputs = append(inputs, outputs[0])
196 })
197
198 f.compatTestTimestamp = android.PathForModuleOut(ctx, "timestamp")
199 rule := android.NewRuleBuilder(pctx, ctx)
200 rule.Command().Text("touch").Output(f.compatTestTimestamp).Implicits(inputs)
201 rule.Build("compat", "compat test timestamp for: "+f.Name())
202}
203
204func (f *compatTestModule) AndroidMkEntries() []android.AndroidMkEntries {
205 return []android.AndroidMkEntries{android.AndroidMkEntries{
206 Class: "FAKE",
207 // OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it.
208 // Without OutputFile this module won't be exported to Makefile.
209 OutputFile: android.OptionalPathForPath(f.compatTestTimestamp),
210 Include: "$(BUILD_PHONY_PACKAGE)",
211 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
212 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
213 entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", f.compatTestTimestamp.String())
214 },
215 },
216 }}
217}