xref: /aosp_15_r20/system/sepolicy/build/soong/compat_cil.go (revision e4a36f4174b17bbab9dc043f4a65dc8d87377290)
1*e4a36f41SAndroid Build Coastguard Worker// Copyright 2021 The Android Open Source Project
2*e4a36f41SAndroid Build Coastguard Worker//
3*e4a36f41SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*e4a36f41SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*e4a36f41SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*e4a36f41SAndroid Build Coastguard Worker//
7*e4a36f41SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*e4a36f41SAndroid Build Coastguard Worker//
9*e4a36f41SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*e4a36f41SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*e4a36f41SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e4a36f41SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*e4a36f41SAndroid Build Coastguard Worker// limitations under the License.
14*e4a36f41SAndroid Build Coastguard Worker
15*e4a36f41SAndroid Build Coastguard Workerpackage selinux
16*e4a36f41SAndroid Build Coastguard Worker
17*e4a36f41SAndroid Build Coastguard Workerimport (
18*e4a36f41SAndroid Build Coastguard Worker	"fmt"
19*e4a36f41SAndroid Build Coastguard Worker
20*e4a36f41SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
21*e4a36f41SAndroid Build Coastguard Worker
22*e4a36f41SAndroid Build Coastguard Worker	"android/soong/android"
23*e4a36f41SAndroid Build Coastguard Worker)
24*e4a36f41SAndroid Build Coastguard Worker
25*e4a36f41SAndroid Build Coastguard Workervar (
26*e4a36f41SAndroid Build Coastguard Worker	compatTestDepTag = dependencyTag{name: "compat_test"}
27*e4a36f41SAndroid Build Coastguard Worker)
28*e4a36f41SAndroid Build Coastguard Worker
29*e4a36f41SAndroid Build Coastguard Workerfunc init() {
30*e4a36f41SAndroid Build Coastguard Worker	ctx := android.InitRegistrationContext
31*e4a36f41SAndroid Build Coastguard Worker	ctx.RegisterModuleType("se_compat_cil", compatCilFactory)
32*e4a36f41SAndroid Build Coastguard Worker	ctx.RegisterModuleType("se_compat_test", compatTestFactory)
33*e4a36f41SAndroid Build Coastguard Worker}
34*e4a36f41SAndroid Build Coastguard Worker
35*e4a36f41SAndroid Build Coastguard Worker// se_compat_cil collects and installs backwards compatibility cil files.
36*e4a36f41SAndroid Build Coastguard Workerfunc compatCilFactory() android.Module {
37*e4a36f41SAndroid Build Coastguard Worker	c := &compatCil{}
38*e4a36f41SAndroid Build Coastguard Worker	c.AddProperties(&c.properties)
39*e4a36f41SAndroid Build Coastguard Worker	android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon)
40*e4a36f41SAndroid Build Coastguard Worker	return c
41*e4a36f41SAndroid Build Coastguard Worker}
42*e4a36f41SAndroid Build Coastguard Worker
43*e4a36f41SAndroid Build Coastguard Workertype compatCil struct {
44*e4a36f41SAndroid Build Coastguard Worker	android.ModuleBase
45*e4a36f41SAndroid Build Coastguard Worker	properties    compatCilProperties
46*e4a36f41SAndroid Build Coastguard Worker	installSource android.OptionalPath
47*e4a36f41SAndroid Build Coastguard Worker	installPath   android.InstallPath
48*e4a36f41SAndroid Build Coastguard Worker}
49*e4a36f41SAndroid Build Coastguard Worker
50*e4a36f41SAndroid Build Coastguard Workertype compatCilProperties struct {
51*e4a36f41SAndroid Build Coastguard Worker	// List of source files. Can reference se_build_files type modules with the ":module" syntax.
52*e4a36f41SAndroid Build Coastguard Worker	Srcs []string `android:"path"`
53*e4a36f41SAndroid Build Coastguard Worker
54*e4a36f41SAndroid Build Coastguard Worker	// Output file name. Defaults to module name if unspecified.
55*e4a36f41SAndroid Build Coastguard Worker	Stem *string
56*e4a36f41SAndroid Build Coastguard Worker
57*e4a36f41SAndroid Build Coastguard Worker	// Target version that this module supports. This module will be ignored if platform sepolicy
58*e4a36f41SAndroid Build Coastguard Worker	// version is same as this module's version.
59*e4a36f41SAndroid Build Coastguard Worker	Version *string
60*e4a36f41SAndroid Build Coastguard Worker}
61*e4a36f41SAndroid Build Coastguard Worker
62*e4a36f41SAndroid Build Coastguard Workerfunc (c *compatCil) stem() string {
63*e4a36f41SAndroid Build Coastguard Worker	return proptools.StringDefault(c.properties.Stem, c.Name())
64*e4a36f41SAndroid Build Coastguard Worker}
65*e4a36f41SAndroid Build Coastguard Worker
66*e4a36f41SAndroid Build Coastguard Workerfunc (c *compatCil) expandSeSources(ctx android.ModuleContext) android.Paths {
67*e4a36f41SAndroid Build Coastguard Worker	return android.PathsForModuleSrc(ctx, c.properties.Srcs)
68*e4a36f41SAndroid Build Coastguard Worker}
69*e4a36f41SAndroid Build Coastguard Worker
70*e4a36f41SAndroid Build Coastguard Workerfunc (c *compatCil) shouldSkipBuild(ctx android.ModuleContext) bool {
71*e4a36f41SAndroid Build Coastguard Worker	return proptools.String(c.properties.Version) == ctx.DeviceConfig().PlatformSepolicyVersion()
72*e4a36f41SAndroid Build Coastguard Worker}
73*e4a36f41SAndroid Build Coastguard Worker
74*e4a36f41SAndroid Build Coastguard Workerfunc (c *compatCil) GenerateAndroidBuildActions(ctx android.ModuleContext) {
75*e4a36f41SAndroid Build Coastguard Worker	if c.ProductSpecific() || c.SocSpecific() || c.DeviceSpecific() {
76*e4a36f41SAndroid Build Coastguard Worker		ctx.ModuleErrorf("Compat cil files only support system and system_ext partitions")
77*e4a36f41SAndroid Build Coastguard Worker	}
78*e4a36f41SAndroid Build Coastguard Worker
79*e4a36f41SAndroid Build Coastguard Worker	if c.shouldSkipBuild(ctx) {
80*e4a36f41SAndroid Build Coastguard Worker		return
81*e4a36f41SAndroid Build Coastguard Worker	}
82*e4a36f41SAndroid Build Coastguard Worker
83*e4a36f41SAndroid Build Coastguard Worker	srcPaths := c.expandSeSources(ctx)
84*e4a36f41SAndroid Build Coastguard Worker	out := android.PathForModuleGen(ctx, c.Name())
85*e4a36f41SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
86*e4a36f41SAndroid Build Coastguard Worker		Rule:        android.Cat,
87*e4a36f41SAndroid Build Coastguard Worker		Inputs:      srcPaths,
88*e4a36f41SAndroid Build Coastguard Worker		Output:      out,
89*e4a36f41SAndroid Build Coastguard Worker		Description: "Combining compat cil for " + c.Name(),
90*e4a36f41SAndroid Build Coastguard Worker	})
91*e4a36f41SAndroid Build Coastguard Worker
92*e4a36f41SAndroid Build Coastguard Worker	c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux", "mapping")
93*e4a36f41SAndroid Build Coastguard Worker	c.installSource = android.OptionalPathForPath(out)
94*e4a36f41SAndroid Build Coastguard Worker	ctx.InstallFile(c.installPath, c.stem(), out)
95*e4a36f41SAndroid Build Coastguard Worker
96*e4a36f41SAndroid Build Coastguard Worker	if c.installSource.Valid() {
97*e4a36f41SAndroid Build Coastguard Worker		ctx.SetOutputFiles(android.Paths{c.installSource.Path()}, "")
98*e4a36f41SAndroid Build Coastguard Worker	}
99*e4a36f41SAndroid Build Coastguard Worker}
100*e4a36f41SAndroid Build Coastguard Worker
101*e4a36f41SAndroid Build Coastguard Workerfunc (c *compatCil) AndroidMkEntries() []android.AndroidMkEntries {
102*e4a36f41SAndroid Build Coastguard Worker	if !c.installSource.Valid() {
103*e4a36f41SAndroid Build Coastguard Worker		return nil
104*e4a36f41SAndroid Build Coastguard Worker	}
105*e4a36f41SAndroid Build Coastguard Worker	return []android.AndroidMkEntries{android.AndroidMkEntries{
106*e4a36f41SAndroid Build Coastguard Worker		Class:      "ETC",
107*e4a36f41SAndroid Build Coastguard Worker		OutputFile: c.installSource,
108*e4a36f41SAndroid Build Coastguard Worker		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
109*e4a36f41SAndroid Build Coastguard Worker			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
110*e4a36f41SAndroid Build Coastguard Worker				entries.SetPath("LOCAL_MODULE_PATH", c.installPath)
111*e4a36f41SAndroid Build Coastguard Worker				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.stem())
112*e4a36f41SAndroid Build Coastguard Worker			},
113*e4a36f41SAndroid Build Coastguard Worker		},
114*e4a36f41SAndroid Build Coastguard Worker	}}
115*e4a36f41SAndroid Build Coastguard Worker}
116*e4a36f41SAndroid Build Coastguard Worker
117*e4a36f41SAndroid Build Coastguard Worker// se_compat_test checks if compat files ({ver}.cil, {ver}.compat.cil) files are compatible with
118*e4a36f41SAndroid Build Coastguard Worker// current policy.
119*e4a36f41SAndroid Build Coastguard Workerfunc compatTestFactory() android.Module {
120*e4a36f41SAndroid Build Coastguard Worker	f := &compatTestModule{}
121*e4a36f41SAndroid Build Coastguard Worker	f.AddProperties(&f.properties)
122*e4a36f41SAndroid Build Coastguard Worker	android.InitAndroidArchModule(f, android.DeviceSupported, android.MultilibCommon)
123*e4a36f41SAndroid Build Coastguard Worker	android.AddLoadHook(f, func(ctx android.LoadHookContext) {
124*e4a36f41SAndroid Build Coastguard Worker		f.loadHook(ctx)
125*e4a36f41SAndroid Build Coastguard Worker	})
126*e4a36f41SAndroid Build Coastguard Worker	return f
127*e4a36f41SAndroid Build Coastguard Worker}
128*e4a36f41SAndroid Build Coastguard Worker
129*e4a36f41SAndroid Build Coastguard Workertype compatTestModule struct {
130*e4a36f41SAndroid Build Coastguard Worker	android.ModuleBase
131*e4a36f41SAndroid Build Coastguard Worker	properties struct {
132*e4a36f41SAndroid Build Coastguard Worker		// Default modules for conf
133*e4a36f41SAndroid Build Coastguard Worker		Defaults []string
134*e4a36f41SAndroid Build Coastguard Worker	}
135*e4a36f41SAndroid Build Coastguard Worker
136*e4a36f41SAndroid Build Coastguard Worker	compatTestTimestamp android.ModuleOutPath
137*e4a36f41SAndroid Build Coastguard Worker}
138*e4a36f41SAndroid Build Coastguard Worker
139*e4a36f41SAndroid Build Coastguard Workerfunc (f *compatTestModule) createCompatTestModule(ctx android.LoadHookContext, ver string) {
140*e4a36f41SAndroid Build Coastguard Worker	srcs := []string{
141*e4a36f41SAndroid Build Coastguard Worker		":plat_sepolicy.cil",
142*e4a36f41SAndroid Build Coastguard Worker		":system_ext_sepolicy.cil",
143*e4a36f41SAndroid Build Coastguard Worker		":product_sepolicy.cil",
144*e4a36f41SAndroid Build Coastguard Worker		fmt.Sprintf(":plat_%s.cil", ver),
145*e4a36f41SAndroid Build Coastguard Worker		fmt.Sprintf(":%s.compat.cil", ver),
146*e4a36f41SAndroid Build Coastguard Worker		fmt.Sprintf(":system_ext_%s.cil", ver),
147*e4a36f41SAndroid Build Coastguard Worker		fmt.Sprintf(":system_ext_%s.compat.cil", ver),
148*e4a36f41SAndroid Build Coastguard Worker		fmt.Sprintf(":product_%s.cil", ver),
149*e4a36f41SAndroid Build Coastguard Worker	}
150*e4a36f41SAndroid Build Coastguard Worker
151*e4a36f41SAndroid Build Coastguard Worker	if ver == ctx.DeviceConfig().BoardSepolicyVers() {
152*e4a36f41SAndroid Build Coastguard Worker		srcs = append(srcs,
153*e4a36f41SAndroid Build Coastguard Worker			":plat_pub_versioned.cil",
154*e4a36f41SAndroid Build Coastguard Worker			":vendor_sepolicy.cil",
155*e4a36f41SAndroid Build Coastguard Worker			":odm_sepolicy.cil",
156*e4a36f41SAndroid Build Coastguard Worker		)
157*e4a36f41SAndroid Build Coastguard Worker	} else {
158*e4a36f41SAndroid Build Coastguard Worker		srcs = append(srcs, fmt.Sprintf(":%s_plat_pub_versioned.cil", ver))
159*e4a36f41SAndroid Build Coastguard Worker	}
160*e4a36f41SAndroid Build Coastguard Worker
161*e4a36f41SAndroid Build Coastguard Worker	compatTestName := fmt.Sprintf("%s_compat_test", ver)
162*e4a36f41SAndroid Build Coastguard Worker	ctx.CreateModule(policyBinaryFactory, &nameProperties{
163*e4a36f41SAndroid Build Coastguard Worker		Name: proptools.StringPtr(compatTestName),
164*e4a36f41SAndroid Build Coastguard Worker	}, &policyBinaryProperties{
165*e4a36f41SAndroid Build Coastguard Worker		Srcs:              srcs,
166*e4a36f41SAndroid Build Coastguard Worker		Ignore_neverallow: proptools.BoolPtr(true),
167*e4a36f41SAndroid Build Coastguard Worker		Installable:       proptools.BoolPtr(false),
168*e4a36f41SAndroid Build Coastguard Worker	})
169*e4a36f41SAndroid Build Coastguard Worker}
170*e4a36f41SAndroid Build Coastguard Worker
171*e4a36f41SAndroid Build Coastguard Workerfunc (f *compatTestModule) loadHook(ctx android.LoadHookContext) {
172*e4a36f41SAndroid Build Coastguard Worker	for _, ver := range ctx.DeviceConfig().PlatformSepolicyCompatVersions() {
173*e4a36f41SAndroid Build Coastguard Worker		f.createCompatTestModule(ctx, ver)
174*e4a36f41SAndroid Build Coastguard Worker	}
175*e4a36f41SAndroid Build Coastguard Worker}
176*e4a36f41SAndroid Build Coastguard Worker
177*e4a36f41SAndroid Build Coastguard Workerfunc (f *compatTestModule) DepsMutator(ctx android.BottomUpMutatorContext) {
178*e4a36f41SAndroid Build Coastguard Worker	for _, ver := range ctx.DeviceConfig().PlatformSepolicyCompatVersions() {
179*e4a36f41SAndroid Build Coastguard Worker		ctx.AddDependency(f, compatTestDepTag, fmt.Sprintf("%s_compat_test", ver))
180*e4a36f41SAndroid Build Coastguard Worker	}
181*e4a36f41SAndroid Build Coastguard Worker}
182*e4a36f41SAndroid Build Coastguard Worker
183*e4a36f41SAndroid Build Coastguard Workerfunc (f *compatTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
184*e4a36f41SAndroid Build Coastguard Worker	if ctx.ModuleName() != "sepolicy_compat_test" || ctx.ModuleDir() != "system/sepolicy/compat" {
185*e4a36f41SAndroid Build Coastguard Worker		// two compat test modules don't make sense.
186*e4a36f41SAndroid Build Coastguard Worker		ctx.ModuleErrorf("There can only be 1 se_compat_test module named sepolicy_compat_test in system/sepolicy/compat")
187*e4a36f41SAndroid Build Coastguard Worker	}
188*e4a36f41SAndroid Build Coastguard Worker	var inputs android.Paths
189*e4a36f41SAndroid Build Coastguard Worker	ctx.VisitDirectDepsWithTag(compatTestDepTag, func(child android.Module) {
190*e4a36f41SAndroid Build Coastguard Worker		outputs := android.OutputFilesForModule(ctx, child, "")
191*e4a36f41SAndroid Build Coastguard Worker		if len(outputs) != 1 {
192*e4a36f41SAndroid Build Coastguard Worker			panic(fmt.Errorf("Module %q should produce exactly one output, but did %q", ctx.OtherModuleName(child), outputs.Strings()))
193*e4a36f41SAndroid Build Coastguard Worker		}
194*e4a36f41SAndroid Build Coastguard Worker
195*e4a36f41SAndroid Build Coastguard Worker		inputs = append(inputs, outputs[0])
196*e4a36f41SAndroid Build Coastguard Worker	})
197*e4a36f41SAndroid Build Coastguard Worker
198*e4a36f41SAndroid Build Coastguard Worker	f.compatTestTimestamp = android.PathForModuleOut(ctx, "timestamp")
199*e4a36f41SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
200*e4a36f41SAndroid Build Coastguard Worker	rule.Command().Text("touch").Output(f.compatTestTimestamp).Implicits(inputs)
201*e4a36f41SAndroid Build Coastguard Worker	rule.Build("compat", "compat test timestamp for: "+f.Name())
202*e4a36f41SAndroid Build Coastguard Worker}
203*e4a36f41SAndroid Build Coastguard Worker
204*e4a36f41SAndroid Build Coastguard Workerfunc (f *compatTestModule) AndroidMkEntries() []android.AndroidMkEntries {
205*e4a36f41SAndroid Build Coastguard Worker	return []android.AndroidMkEntries{android.AndroidMkEntries{
206*e4a36f41SAndroid Build Coastguard Worker		Class: "FAKE",
207*e4a36f41SAndroid Build Coastguard Worker		// OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it.
208*e4a36f41SAndroid Build Coastguard Worker		// Without OutputFile this module won't be exported to Makefile.
209*e4a36f41SAndroid Build Coastguard Worker		OutputFile: android.OptionalPathForPath(f.compatTestTimestamp),
210*e4a36f41SAndroid Build Coastguard Worker		Include:    "$(BUILD_PHONY_PACKAGE)",
211*e4a36f41SAndroid Build Coastguard Worker		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
212*e4a36f41SAndroid Build Coastguard Worker			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
213*e4a36f41SAndroid Build Coastguard Worker				entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", f.compatTestTimestamp.String())
214*e4a36f41SAndroid Build Coastguard Worker			},
215*e4a36f41SAndroid Build Coastguard Worker		},
216*e4a36f41SAndroid Build Coastguard Worker	}}
217*e4a36f41SAndroid Build Coastguard Worker}
218