xref: /aosp_15_r20/system/sepolicy/build/soong/selinux_contexts.go (revision e4a36f4174b17bbab9dc043f4a65dc8d87377290)
1*e4a36f41SAndroid Build Coastguard Worker// Copyright (C) 2019 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	"io"
20*e4a36f41SAndroid Build Coastguard Worker
21*e4a36f41SAndroid Build Coastguard Worker	"github.com/google/blueprint"
22*e4a36f41SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
23*e4a36f41SAndroid Build Coastguard Worker
24*e4a36f41SAndroid Build Coastguard Worker	"android/soong/android"
25*e4a36f41SAndroid Build Coastguard Worker	"android/soong/sysprop"
26*e4a36f41SAndroid Build Coastguard Worker)
27*e4a36f41SAndroid Build Coastguard Worker
28*e4a36f41SAndroid Build Coastguard Workertype selinuxContextsProperties struct {
29*e4a36f41SAndroid Build Coastguard Worker	// Filenames under sepolicy directories, which will be used to generate contexts file.
30*e4a36f41SAndroid Build Coastguard Worker	Srcs []string `android:"path"`
31*e4a36f41SAndroid Build Coastguard Worker
32*e4a36f41SAndroid Build Coastguard Worker	// Output file name. Defaults to module name
33*e4a36f41SAndroid Build Coastguard Worker	Stem *string
34*e4a36f41SAndroid Build Coastguard Worker
35*e4a36f41SAndroid Build Coastguard Worker	Product_variables struct {
36*e4a36f41SAndroid Build Coastguard Worker		Address_sanitize struct {
37*e4a36f41SAndroid Build Coastguard Worker			Srcs []string `android:"path"`
38*e4a36f41SAndroid Build Coastguard Worker		}
39*e4a36f41SAndroid Build Coastguard Worker	}
40*e4a36f41SAndroid Build Coastguard Worker
41*e4a36f41SAndroid Build Coastguard Worker	// Whether the comments in generated contexts file will be removed or not.
42*e4a36f41SAndroid Build Coastguard Worker	Remove_comment *bool
43*e4a36f41SAndroid Build Coastguard Worker
44*e4a36f41SAndroid Build Coastguard Worker	// Whether the result context file is sorted with fc_sort or not.
45*e4a36f41SAndroid Build Coastguard Worker	Fc_sort *bool
46*e4a36f41SAndroid Build Coastguard Worker
47*e4a36f41SAndroid Build Coastguard Worker	// Make this module available when building for recovery
48*e4a36f41SAndroid Build Coastguard Worker	Recovery_available *bool
49*e4a36f41SAndroid Build Coastguard Worker
50*e4a36f41SAndroid Build Coastguard Worker	// Board api level of policy files. Set "current" for RELEASE_BOARD_API_LEVEL, or a direct
51*e4a36f41SAndroid Build Coastguard Worker	// version string (e.g. "202404"). Defaults to "current"
52*e4a36f41SAndroid Build Coastguard Worker	Board_api_level *string
53*e4a36f41SAndroid Build Coastguard Worker}
54*e4a36f41SAndroid Build Coastguard Worker
55*e4a36f41SAndroid Build Coastguard Workertype seappProperties struct {
56*e4a36f41SAndroid Build Coastguard Worker	// Files containing neverallow rules.
57*e4a36f41SAndroid Build Coastguard Worker	Neverallow_files []string `android:"path"`
58*e4a36f41SAndroid Build Coastguard Worker
59*e4a36f41SAndroid Build Coastguard Worker	// Precompiled sepolicy binary file which will be fed to checkseapp.
60*e4a36f41SAndroid Build Coastguard Worker	Sepolicy *string `android:"path"`
61*e4a36f41SAndroid Build Coastguard Worker}
62*e4a36f41SAndroid Build Coastguard Worker
63*e4a36f41SAndroid Build Coastguard Workertype selinuxContextsModule struct {
64*e4a36f41SAndroid Build Coastguard Worker	android.ModuleBase
65*e4a36f41SAndroid Build Coastguard Worker	android.DefaultableModuleBase
66*e4a36f41SAndroid Build Coastguard Worker	flaggableModuleBase
67*e4a36f41SAndroid Build Coastguard Worker
68*e4a36f41SAndroid Build Coastguard Worker	properties      selinuxContextsProperties
69*e4a36f41SAndroid Build Coastguard Worker	seappProperties seappProperties
70*e4a36f41SAndroid Build Coastguard Worker	build           func(ctx android.ModuleContext, inputs android.Paths) android.Path
71*e4a36f41SAndroid Build Coastguard Worker	deps            func(ctx android.BottomUpMutatorContext)
72*e4a36f41SAndroid Build Coastguard Worker	outputPath      android.Path
73*e4a36f41SAndroid Build Coastguard Worker	installPath     android.InstallPath
74*e4a36f41SAndroid Build Coastguard Worker}
75*e4a36f41SAndroid Build Coastguard Worker
76*e4a36f41SAndroid Build Coastguard Workervar _ flaggableModule = (*selinuxContextsModule)(nil)
77*e4a36f41SAndroid Build Coastguard Worker
78*e4a36f41SAndroid Build Coastguard Workervar (
79*e4a36f41SAndroid Build Coastguard Worker	reuseContextsDepTag  = dependencyTag{name: "reuseContexts"}
80*e4a36f41SAndroid Build Coastguard Worker	syspropLibraryDepTag = dependencyTag{name: "sysprop_library"}
81*e4a36f41SAndroid Build Coastguard Worker)
82*e4a36f41SAndroid Build Coastguard Worker
83*e4a36f41SAndroid Build Coastguard Workerfunc init() {
84*e4a36f41SAndroid Build Coastguard Worker	pctx.HostBinToolVariable("fc_sort", "fc_sort")
85*e4a36f41SAndroid Build Coastguard Worker
86*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("contexts_defaults", contextsDefaultsFactory)
87*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("file_contexts", fileFactory)
88*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("hwservice_contexts", hwServiceFactory)
89*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("property_contexts", propertyFactory)
90*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("service_contexts", serviceFactory)
91*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("keystore2_key_contexts", keystoreKeyFactory)
92*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("seapp_contexts", seappFactory)
93*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("vndservice_contexts", vndServiceFactory)
94*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("tee_service_contexts", teeServiceFactory)
95*e4a36f41SAndroid Build Coastguard Worker
96*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("file_contexts_test", fileContextsTestFactory)
97*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("property_contexts_test", propertyContextsTestFactory)
98*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("hwservice_contexts_test", hwserviceContextsTestFactory)
99*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("service_contexts_test", serviceContextsTestFactory)
100*e4a36f41SAndroid Build Coastguard Worker	android.RegisterModuleType("vndservice_contexts_test", vndServiceContextsTestFactory)
101*e4a36f41SAndroid Build Coastguard Worker}
102*e4a36f41SAndroid Build Coastguard Worker
103*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) InstallInRoot() bool {
104*e4a36f41SAndroid Build Coastguard Worker	return m.InRecovery()
105*e4a36f41SAndroid Build Coastguard Worker}
106*e4a36f41SAndroid Build Coastguard Worker
107*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) InstallInRecovery() bool {
108*e4a36f41SAndroid Build Coastguard Worker	// ModuleBase.InRecovery() checks the image variant
109*e4a36f41SAndroid Build Coastguard Worker	return m.InRecovery()
110*e4a36f41SAndroid Build Coastguard Worker}
111*e4a36f41SAndroid Build Coastguard Worker
112*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) onlyInRecovery() bool {
113*e4a36f41SAndroid Build Coastguard Worker	// ModuleBase.InstallInRecovery() checks commonProperties.Recovery property
114*e4a36f41SAndroid Build Coastguard Worker	return m.ModuleBase.InstallInRecovery()
115*e4a36f41SAndroid Build Coastguard Worker}
116*e4a36f41SAndroid Build Coastguard Worker
117*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) DepsMutator(ctx android.BottomUpMutatorContext) {
118*e4a36f41SAndroid Build Coastguard Worker	m.flagDeps(ctx)
119*e4a36f41SAndroid Build Coastguard Worker
120*e4a36f41SAndroid Build Coastguard Worker	if m.deps != nil {
121*e4a36f41SAndroid Build Coastguard Worker		m.deps(ctx)
122*e4a36f41SAndroid Build Coastguard Worker	}
123*e4a36f41SAndroid Build Coastguard Worker
124*e4a36f41SAndroid Build Coastguard Worker	if m.InRecovery() && !m.onlyInRecovery() {
125*e4a36f41SAndroid Build Coastguard Worker		ctx.AddFarVariationDependencies([]blueprint.Variation{
126*e4a36f41SAndroid Build Coastguard Worker			{Mutator: "image", Variation: android.CoreVariation},
127*e4a36f41SAndroid Build Coastguard Worker		}, reuseContextsDepTag, ctx.ModuleName())
128*e4a36f41SAndroid Build Coastguard Worker	}
129*e4a36f41SAndroid Build Coastguard Worker}
130*e4a36f41SAndroid Build Coastguard Worker
131*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) propertyContextsDeps(ctx android.BottomUpMutatorContext) {
132*e4a36f41SAndroid Build Coastguard Worker	for _, lib := range sysprop.SyspropLibraries(ctx.Config()) {
133*e4a36f41SAndroid Build Coastguard Worker		ctx.AddFarVariationDependencies([]blueprint.Variation{}, syspropLibraryDepTag, lib)
134*e4a36f41SAndroid Build Coastguard Worker	}
135*e4a36f41SAndroid Build Coastguard Worker}
136*e4a36f41SAndroid Build Coastguard Worker
137*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) stem() string {
138*e4a36f41SAndroid Build Coastguard Worker	return proptools.StringDefault(m.properties.Stem, m.Name())
139*e4a36f41SAndroid Build Coastguard Worker}
140*e4a36f41SAndroid Build Coastguard Worker
141*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
142*e4a36f41SAndroid Build Coastguard Worker	if m.InRecovery() {
143*e4a36f41SAndroid Build Coastguard Worker		// Installing context files at the root of the recovery partition
144*e4a36f41SAndroid Build Coastguard Worker		m.installPath = android.PathForModuleInstall(ctx)
145*e4a36f41SAndroid Build Coastguard Worker	} else {
146*e4a36f41SAndroid Build Coastguard Worker		m.installPath = android.PathForModuleInstall(ctx, "etc", "selinux")
147*e4a36f41SAndroid Build Coastguard Worker	}
148*e4a36f41SAndroid Build Coastguard Worker
149*e4a36f41SAndroid Build Coastguard Worker	if m.InRecovery() && !m.onlyInRecovery() {
150*e4a36f41SAndroid Build Coastguard Worker		dep := ctx.GetDirectDepWithTag(m.Name(), reuseContextsDepTag)
151*e4a36f41SAndroid Build Coastguard Worker
152*e4a36f41SAndroid Build Coastguard Worker		if reuseDeps, ok := dep.(*selinuxContextsModule); ok {
153*e4a36f41SAndroid Build Coastguard Worker			m.outputPath = reuseDeps.outputPath
154*e4a36f41SAndroid Build Coastguard Worker			ctx.InstallFile(m.installPath, m.stem(), m.outputPath)
155*e4a36f41SAndroid Build Coastguard Worker			return
156*e4a36f41SAndroid Build Coastguard Worker		}
157*e4a36f41SAndroid Build Coastguard Worker	}
158*e4a36f41SAndroid Build Coastguard Worker
159*e4a36f41SAndroid Build Coastguard Worker	m.outputPath = m.build(ctx, android.PathsForModuleSrc(ctx, m.properties.Srcs))
160*e4a36f41SAndroid Build Coastguard Worker	ctx.InstallFile(m.installPath, m.stem(), m.outputPath)
161*e4a36f41SAndroid Build Coastguard Worker
162*e4a36f41SAndroid Build Coastguard Worker	ctx.SetOutputFiles([]android.Path{m.outputPath}, "")
163*e4a36f41SAndroid Build Coastguard Worker}
164*e4a36f41SAndroid Build Coastguard Worker
165*e4a36f41SAndroid Build Coastguard Workerfunc newModule() *selinuxContextsModule {
166*e4a36f41SAndroid Build Coastguard Worker	m := &selinuxContextsModule{}
167*e4a36f41SAndroid Build Coastguard Worker	m.AddProperties(
168*e4a36f41SAndroid Build Coastguard Worker		&m.properties,
169*e4a36f41SAndroid Build Coastguard Worker		&m.seappProperties,
170*e4a36f41SAndroid Build Coastguard Worker	)
171*e4a36f41SAndroid Build Coastguard Worker	initFlaggableModule(m)
172*e4a36f41SAndroid Build Coastguard Worker	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
173*e4a36f41SAndroid Build Coastguard Worker	android.InitDefaultableModule(m)
174*e4a36f41SAndroid Build Coastguard Worker	android.AddLoadHook(m, func(ctx android.LoadHookContext) {
175*e4a36f41SAndroid Build Coastguard Worker		m.selinuxContextsHook(ctx)
176*e4a36f41SAndroid Build Coastguard Worker	})
177*e4a36f41SAndroid Build Coastguard Worker	return m
178*e4a36f41SAndroid Build Coastguard Worker}
179*e4a36f41SAndroid Build Coastguard Worker
180*e4a36f41SAndroid Build Coastguard Workertype contextsDefaults struct {
181*e4a36f41SAndroid Build Coastguard Worker	android.ModuleBase
182*e4a36f41SAndroid Build Coastguard Worker	android.DefaultsModuleBase
183*e4a36f41SAndroid Build Coastguard Worker}
184*e4a36f41SAndroid Build Coastguard Worker
185*e4a36f41SAndroid Build Coastguard Worker// contexts_defaults provides a set of properties that can be inherited by other contexts modules.
186*e4a36f41SAndroid Build Coastguard Worker// (file_contexts, property_contexts, seapp_contexts, etc.) A module can use the properties from a
187*e4a36f41SAndroid Build Coastguard Worker// contexts_defaults using `defaults: ["<:default_module_name>"]`. Properties of both modules are
188*e4a36f41SAndroid Build Coastguard Worker// erged (when possible) by prepending the default module's values to the depending module's values.
189*e4a36f41SAndroid Build Coastguard Workerfunc contextsDefaultsFactory() android.Module {
190*e4a36f41SAndroid Build Coastguard Worker	m := &contextsDefaults{}
191*e4a36f41SAndroid Build Coastguard Worker	m.AddProperties(
192*e4a36f41SAndroid Build Coastguard Worker		&selinuxContextsProperties{},
193*e4a36f41SAndroid Build Coastguard Worker		&seappProperties{},
194*e4a36f41SAndroid Build Coastguard Worker		&flaggableModuleProperties{},
195*e4a36f41SAndroid Build Coastguard Worker	)
196*e4a36f41SAndroid Build Coastguard Worker	android.InitDefaultsModule(m)
197*e4a36f41SAndroid Build Coastguard Worker	return m
198*e4a36f41SAndroid Build Coastguard Worker}
199*e4a36f41SAndroid Build Coastguard Worker
200*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) selinuxContextsHook(ctx android.LoadHookContext) {
201*e4a36f41SAndroid Build Coastguard Worker	// TODO: clean this up to use build/soong/android/variable.go after b/79249983
202*e4a36f41SAndroid Build Coastguard Worker	var srcs []string
203*e4a36f41SAndroid Build Coastguard Worker
204*e4a36f41SAndroid Build Coastguard Worker	for _, sanitize := range ctx.Config().SanitizeDevice() {
205*e4a36f41SAndroid Build Coastguard Worker		if sanitize == "address" {
206*e4a36f41SAndroid Build Coastguard Worker			srcs = append(srcs, m.properties.Product_variables.Address_sanitize.Srcs...)
207*e4a36f41SAndroid Build Coastguard Worker			break
208*e4a36f41SAndroid Build Coastguard Worker		}
209*e4a36f41SAndroid Build Coastguard Worker	}
210*e4a36f41SAndroid Build Coastguard Worker
211*e4a36f41SAndroid Build Coastguard Worker	m.properties.Srcs = append(m.properties.Srcs, srcs...)
212*e4a36f41SAndroid Build Coastguard Worker}
213*e4a36f41SAndroid Build Coastguard Worker
214*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) AndroidMk() android.AndroidMkData {
215*e4a36f41SAndroid Build Coastguard Worker	nameSuffix := ""
216*e4a36f41SAndroid Build Coastguard Worker	if m.InRecovery() && !m.onlyInRecovery() {
217*e4a36f41SAndroid Build Coastguard Worker		nameSuffix = ".recovery"
218*e4a36f41SAndroid Build Coastguard Worker	}
219*e4a36f41SAndroid Build Coastguard Worker	return android.AndroidMkData{
220*e4a36f41SAndroid Build Coastguard Worker		Class:      "ETC",
221*e4a36f41SAndroid Build Coastguard Worker		OutputFile: android.OptionalPathForPath(m.outputPath),
222*e4a36f41SAndroid Build Coastguard Worker		SubName:    nameSuffix,
223*e4a36f41SAndroid Build Coastguard Worker		Extra: []android.AndroidMkExtraFunc{
224*e4a36f41SAndroid Build Coastguard Worker			func(w io.Writer, outputFile android.Path) {
225*e4a36f41SAndroid Build Coastguard Worker				fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", m.installPath.String())
226*e4a36f41SAndroid Build Coastguard Worker				fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", m.stem())
227*e4a36f41SAndroid Build Coastguard Worker			},
228*e4a36f41SAndroid Build Coastguard Worker		},
229*e4a36f41SAndroid Build Coastguard Worker	}
230*e4a36f41SAndroid Build Coastguard Worker}
231*e4a36f41SAndroid Build Coastguard Worker
232*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) ImageMutatorBegin(ctx android.ImageInterfaceContext) {
233*e4a36f41SAndroid Build Coastguard Worker	if proptools.Bool(m.properties.Recovery_available) && m.ModuleBase.InstallInRecovery() {
234*e4a36f41SAndroid Build Coastguard Worker		ctx.PropertyErrorf("recovery_available",
235*e4a36f41SAndroid Build Coastguard Worker			"doesn't make sense at the same time as `recovery: true`")
236*e4a36f41SAndroid Build Coastguard Worker	}
237*e4a36f41SAndroid Build Coastguard Worker}
238*e4a36f41SAndroid Build Coastguard Worker
239*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
240*e4a36f41SAndroid Build Coastguard Worker	return false
241*e4a36f41SAndroid Build Coastguard Worker}
242*e4a36f41SAndroid Build Coastguard Worker
243*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
244*e4a36f41SAndroid Build Coastguard Worker	return false
245*e4a36f41SAndroid Build Coastguard Worker}
246*e4a36f41SAndroid Build Coastguard Worker
247*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
248*e4a36f41SAndroid Build Coastguard Worker	return !m.ModuleBase.InstallInRecovery()
249*e4a36f41SAndroid Build Coastguard Worker}
250*e4a36f41SAndroid Build Coastguard Worker
251*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
252*e4a36f41SAndroid Build Coastguard Worker	return false
253*e4a36f41SAndroid Build Coastguard Worker}
254*e4a36f41SAndroid Build Coastguard Worker
255*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
256*e4a36f41SAndroid Build Coastguard Worker	return false
257*e4a36f41SAndroid Build Coastguard Worker}
258*e4a36f41SAndroid Build Coastguard Worker
259*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
260*e4a36f41SAndroid Build Coastguard Worker	return false
261*e4a36f41SAndroid Build Coastguard Worker}
262*e4a36f41SAndroid Build Coastguard Worker
263*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
264*e4a36f41SAndroid Build Coastguard Worker	return m.ModuleBase.InstallInRecovery() || proptools.Bool(m.properties.Recovery_available)
265*e4a36f41SAndroid Build Coastguard Worker}
266*e4a36f41SAndroid Build Coastguard Worker
267*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
268*e4a36f41SAndroid Build Coastguard Worker	return nil
269*e4a36f41SAndroid Build Coastguard Worker}
270*e4a36f41SAndroid Build Coastguard Worker
271*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
272*e4a36f41SAndroid Build Coastguard Worker}
273*e4a36f41SAndroid Build Coastguard Worker
274*e4a36f41SAndroid Build Coastguard Workervar _ android.ImageInterface = (*selinuxContextsModule)(nil)
275*e4a36f41SAndroid Build Coastguard Worker
276*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) buildGeneralContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
277*e4a36f41SAndroid Build Coastguard Worker	builtContext := pathForModuleOut(ctx, ctx.ModuleName()+"_m4out")
278*e4a36f41SAndroid Build Coastguard Worker
279*e4a36f41SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
280*e4a36f41SAndroid Build Coastguard Worker
281*e4a36f41SAndroid Build Coastguard Worker	newlineFile := pathForModuleOut(ctx, "newline")
282*e4a36f41SAndroid Build Coastguard Worker
283*e4a36f41SAndroid Build Coastguard Worker	rule.Command().Text("echo").FlagWithOutput("> ", newlineFile)
284*e4a36f41SAndroid Build Coastguard Worker	rule.Temporary(newlineFile)
285*e4a36f41SAndroid Build Coastguard Worker
286*e4a36f41SAndroid Build Coastguard Worker	var inputsWithNewline android.Paths
287*e4a36f41SAndroid Build Coastguard Worker	for _, input := range inputs {
288*e4a36f41SAndroid Build Coastguard Worker		inputsWithNewline = append(inputsWithNewline, input, newlineFile)
289*e4a36f41SAndroid Build Coastguard Worker	}
290*e4a36f41SAndroid Build Coastguard Worker
291*e4a36f41SAndroid Build Coastguard Worker	flags := m.getBuildFlags(ctx)
292*e4a36f41SAndroid Build Coastguard Worker	rule.Command().
293*e4a36f41SAndroid Build Coastguard Worker		Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
294*e4a36f41SAndroid Build Coastguard Worker		Text("--fatal-warnings -s").
295*e4a36f41SAndroid Build Coastguard Worker		FlagForEachArg("-D", ctx.DeviceConfig().SepolicyM4Defs()).
296*e4a36f41SAndroid Build Coastguard Worker		Flag(boardApiLevelToM4Macro(ctx, m.properties.Board_api_level)).
297*e4a36f41SAndroid Build Coastguard Worker		Flags(flagsToM4Macros(flags)).
298*e4a36f41SAndroid Build Coastguard Worker		Inputs(inputsWithNewline).
299*e4a36f41SAndroid Build Coastguard Worker		FlagWithOutput("> ", builtContext)
300*e4a36f41SAndroid Build Coastguard Worker
301*e4a36f41SAndroid Build Coastguard Worker	if proptools.Bool(m.properties.Remove_comment) {
302*e4a36f41SAndroid Build Coastguard Worker		rule.Temporary(builtContext)
303*e4a36f41SAndroid Build Coastguard Worker
304*e4a36f41SAndroid Build Coastguard Worker		remove_comment_output := pathForModuleOut(ctx, ctx.ModuleName()+"_remove_comment")
305*e4a36f41SAndroid Build Coastguard Worker
306*e4a36f41SAndroid Build Coastguard Worker		rule.Command().
307*e4a36f41SAndroid Build Coastguard Worker			Text("sed -e 's/#.*$//' -e '/^$/d'").
308*e4a36f41SAndroid Build Coastguard Worker			Input(builtContext).
309*e4a36f41SAndroid Build Coastguard Worker			FlagWithOutput("> ", remove_comment_output)
310*e4a36f41SAndroid Build Coastguard Worker
311*e4a36f41SAndroid Build Coastguard Worker		builtContext = remove_comment_output
312*e4a36f41SAndroid Build Coastguard Worker	}
313*e4a36f41SAndroid Build Coastguard Worker
314*e4a36f41SAndroid Build Coastguard Worker	if proptools.Bool(m.properties.Fc_sort) {
315*e4a36f41SAndroid Build Coastguard Worker		rule.Temporary(builtContext)
316*e4a36f41SAndroid Build Coastguard Worker
317*e4a36f41SAndroid Build Coastguard Worker		sorted_output := pathForModuleOut(ctx, ctx.ModuleName()+"_sorted")
318*e4a36f41SAndroid Build Coastguard Worker
319*e4a36f41SAndroid Build Coastguard Worker		rule.Command().
320*e4a36f41SAndroid Build Coastguard Worker			Tool(ctx.Config().HostToolPath(ctx, "fc_sort")).
321*e4a36f41SAndroid Build Coastguard Worker			FlagWithInput("-i ", builtContext).
322*e4a36f41SAndroid Build Coastguard Worker			FlagWithOutput("-o ", sorted_output)
323*e4a36f41SAndroid Build Coastguard Worker
324*e4a36f41SAndroid Build Coastguard Worker		builtContext = sorted_output
325*e4a36f41SAndroid Build Coastguard Worker	}
326*e4a36f41SAndroid Build Coastguard Worker
327*e4a36f41SAndroid Build Coastguard Worker	ret := pathForModuleOut(ctx, m.stem())
328*e4a36f41SAndroid Build Coastguard Worker	rule.Temporary(builtContext)
329*e4a36f41SAndroid Build Coastguard Worker	rule.Command().Text("cp").Input(builtContext).Output(ret)
330*e4a36f41SAndroid Build Coastguard Worker
331*e4a36f41SAndroid Build Coastguard Worker	rule.DeleteTemporaryFiles()
332*e4a36f41SAndroid Build Coastguard Worker	rule.Build("selinux_contexts", "building contexts: "+m.Name())
333*e4a36f41SAndroid Build Coastguard Worker
334*e4a36f41SAndroid Build Coastguard Worker	return ret
335*e4a36f41SAndroid Build Coastguard Worker}
336*e4a36f41SAndroid Build Coastguard Worker
337*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) buildFileContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
338*e4a36f41SAndroid Build Coastguard Worker	if m.properties.Remove_comment == nil {
339*e4a36f41SAndroid Build Coastguard Worker		m.properties.Remove_comment = proptools.BoolPtr(true)
340*e4a36f41SAndroid Build Coastguard Worker	}
341*e4a36f41SAndroid Build Coastguard Worker	return m.buildGeneralContexts(ctx, inputs)
342*e4a36f41SAndroid Build Coastguard Worker}
343*e4a36f41SAndroid Build Coastguard Worker
344*e4a36f41SAndroid Build Coastguard Workerfunc fileFactory() android.Module {
345*e4a36f41SAndroid Build Coastguard Worker	m := newModule()
346*e4a36f41SAndroid Build Coastguard Worker	m.build = m.buildFileContexts
347*e4a36f41SAndroid Build Coastguard Worker	return m
348*e4a36f41SAndroid Build Coastguard Worker}
349*e4a36f41SAndroid Build Coastguard Worker
350*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) buildServiceContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
351*e4a36f41SAndroid Build Coastguard Worker	if m.properties.Remove_comment == nil {
352*e4a36f41SAndroid Build Coastguard Worker		m.properties.Remove_comment = proptools.BoolPtr(true)
353*e4a36f41SAndroid Build Coastguard Worker	}
354*e4a36f41SAndroid Build Coastguard Worker
355*e4a36f41SAndroid Build Coastguard Worker	return m.buildGeneralContexts(ctx, inputs)
356*e4a36f41SAndroid Build Coastguard Worker}
357*e4a36f41SAndroid Build Coastguard Worker
358*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) checkVendorPropertyNamespace(ctx android.ModuleContext, input android.Path) android.Path {
359*e4a36f41SAndroid Build Coastguard Worker	shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
360*e4a36f41SAndroid Build Coastguard Worker	ApiLevelR := android.ApiLevelOrPanic(ctx, "R")
361*e4a36f41SAndroid Build Coastguard Worker
362*e4a36f41SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
363*e4a36f41SAndroid Build Coastguard Worker
364*e4a36f41SAndroid Build Coastguard Worker	// This list is from vts_treble_sys_prop_test.
365*e4a36f41SAndroid Build Coastguard Worker	allowedPropertyPrefixes := []string{
366*e4a36f41SAndroid Build Coastguard Worker		"ctl.odm.",
367*e4a36f41SAndroid Build Coastguard Worker		"ctl.vendor.",
368*e4a36f41SAndroid Build Coastguard Worker		"ctl.start$odm.",
369*e4a36f41SAndroid Build Coastguard Worker		"ctl.start$vendor.",
370*e4a36f41SAndroid Build Coastguard Worker		"ctl.stop$odm.",
371*e4a36f41SAndroid Build Coastguard Worker		"ctl.stop$vendor.",
372*e4a36f41SAndroid Build Coastguard Worker		"init.svc.odm.",
373*e4a36f41SAndroid Build Coastguard Worker		"init.svc.vendor.",
374*e4a36f41SAndroid Build Coastguard Worker		"ro.boot.",
375*e4a36f41SAndroid Build Coastguard Worker		"ro.hardware.",
376*e4a36f41SAndroid Build Coastguard Worker		"ro.odm.",
377*e4a36f41SAndroid Build Coastguard Worker		"ro.vendor.",
378*e4a36f41SAndroid Build Coastguard Worker		"odm.",
379*e4a36f41SAndroid Build Coastguard Worker		"persist.odm.",
380*e4a36f41SAndroid Build Coastguard Worker		"persist.vendor.",
381*e4a36f41SAndroid Build Coastguard Worker		"vendor.",
382*e4a36f41SAndroid Build Coastguard Worker	}
383*e4a36f41SAndroid Build Coastguard Worker
384*e4a36f41SAndroid Build Coastguard Worker	// persist.camera is also allowed for devices launching with R or eariler
385*e4a36f41SAndroid Build Coastguard Worker	if shippingApiLevel.LessThanOrEqualTo(ApiLevelR) {
386*e4a36f41SAndroid Build Coastguard Worker		allowedPropertyPrefixes = append(allowedPropertyPrefixes, "persist.camera.")
387*e4a36f41SAndroid Build Coastguard Worker	}
388*e4a36f41SAndroid Build Coastguard Worker
389*e4a36f41SAndroid Build Coastguard Worker	var allowedContextPrefixes []string
390*e4a36f41SAndroid Build Coastguard Worker
391*e4a36f41SAndroid Build Coastguard Worker	if shippingApiLevel.GreaterThanOrEqualTo(ApiLevelR) {
392*e4a36f41SAndroid Build Coastguard Worker		// This list is from vts_treble_sys_prop_test.
393*e4a36f41SAndroid Build Coastguard Worker		allowedContextPrefixes = []string{
394*e4a36f41SAndroid Build Coastguard Worker			"vendor_",
395*e4a36f41SAndroid Build Coastguard Worker			"odm_",
396*e4a36f41SAndroid Build Coastguard Worker		}
397*e4a36f41SAndroid Build Coastguard Worker	}
398*e4a36f41SAndroid Build Coastguard Worker
399*e4a36f41SAndroid Build Coastguard Worker	cmd := rule.Command().
400*e4a36f41SAndroid Build Coastguard Worker		BuiltTool("check_prop_prefix").
401*e4a36f41SAndroid Build Coastguard Worker		FlagWithInput("--property-contexts ", input).
402*e4a36f41SAndroid Build Coastguard Worker		FlagForEachArg("--allowed-property-prefix ", proptools.ShellEscapeList(allowedPropertyPrefixes)). // contains shell special character '$'
403*e4a36f41SAndroid Build Coastguard Worker		FlagForEachArg("--allowed-context-prefix ", allowedContextPrefixes)
404*e4a36f41SAndroid Build Coastguard Worker
405*e4a36f41SAndroid Build Coastguard Worker	if !ctx.DeviceConfig().BuildBrokenVendorPropertyNamespace() {
406*e4a36f41SAndroid Build Coastguard Worker		cmd.Flag("--strict")
407*e4a36f41SAndroid Build Coastguard Worker	}
408*e4a36f41SAndroid Build Coastguard Worker
409*e4a36f41SAndroid Build Coastguard Worker	out := pathForModuleOut(ctx, ctx.ModuleName()+"_namespace_checked")
410*e4a36f41SAndroid Build Coastguard Worker	rule.Command().Text("cp -f").Input(input).Output(out)
411*e4a36f41SAndroid Build Coastguard Worker	rule.Build("check_namespace", "checking namespace of "+ctx.ModuleName())
412*e4a36f41SAndroid Build Coastguard Worker	return out
413*e4a36f41SAndroid Build Coastguard Worker}
414*e4a36f41SAndroid Build Coastguard Worker
415*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) buildPropertyContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
416*e4a36f41SAndroid Build Coastguard Worker	// vendor/odm properties are enforced for devices launching with Android Q or later. So, if
417*e4a36f41SAndroid Build Coastguard Worker	// vendor/odm, make sure that only vendor/odm properties exist.
418*e4a36f41SAndroid Build Coastguard Worker	builtCtxFile := m.buildGeneralContexts(ctx, inputs)
419*e4a36f41SAndroid Build Coastguard Worker
420*e4a36f41SAndroid Build Coastguard Worker	shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
421*e4a36f41SAndroid Build Coastguard Worker	ApiLevelQ := android.ApiLevelOrPanic(ctx, "Q")
422*e4a36f41SAndroid Build Coastguard Worker	if (ctx.SocSpecific() || ctx.DeviceSpecific()) && shippingApiLevel.GreaterThanOrEqualTo(ApiLevelQ) {
423*e4a36f41SAndroid Build Coastguard Worker		builtCtxFile = m.checkVendorPropertyNamespace(ctx, builtCtxFile)
424*e4a36f41SAndroid Build Coastguard Worker	}
425*e4a36f41SAndroid Build Coastguard Worker
426*e4a36f41SAndroid Build Coastguard Worker	var apiFiles android.Paths
427*e4a36f41SAndroid Build Coastguard Worker	ctx.VisitDirectDepsWithTag(syspropLibraryDepTag, func(c android.Module) {
428*e4a36f41SAndroid Build Coastguard Worker		i, ok := c.(interface{ CurrentSyspropApiFile() android.OptionalPath })
429*e4a36f41SAndroid Build Coastguard Worker		if !ok {
430*e4a36f41SAndroid Build Coastguard Worker			panic(fmt.Errorf("unknown dependency %q for %q", ctx.OtherModuleName(c), ctx.ModuleName()))
431*e4a36f41SAndroid Build Coastguard Worker		}
432*e4a36f41SAndroid Build Coastguard Worker		if api := i.CurrentSyspropApiFile(); api.Valid() {
433*e4a36f41SAndroid Build Coastguard Worker			apiFiles = append(apiFiles, api.Path())
434*e4a36f41SAndroid Build Coastguard Worker		}
435*e4a36f41SAndroid Build Coastguard Worker	})
436*e4a36f41SAndroid Build Coastguard Worker
437*e4a36f41SAndroid Build Coastguard Worker	// check compatibility with sysprop_library
438*e4a36f41SAndroid Build Coastguard Worker	if len(apiFiles) > 0 {
439*e4a36f41SAndroid Build Coastguard Worker		out := pathForModuleOut(ctx, ctx.ModuleName()+"_api_checked")
440*e4a36f41SAndroid Build Coastguard Worker		rule := android.NewRuleBuilder(pctx, ctx)
441*e4a36f41SAndroid Build Coastguard Worker
442*e4a36f41SAndroid Build Coastguard Worker		msg := `\n******************************\n` +
443*e4a36f41SAndroid Build Coastguard Worker			`API of sysprop_library doesn't match with property_contexts\n` +
444*e4a36f41SAndroid Build Coastguard Worker			`Please fix the breakage and rebuild.\n` +
445*e4a36f41SAndroid Build Coastguard Worker			`******************************\n`
446*e4a36f41SAndroid Build Coastguard Worker
447*e4a36f41SAndroid Build Coastguard Worker		rule.Command().
448*e4a36f41SAndroid Build Coastguard Worker			Text("( ").
449*e4a36f41SAndroid Build Coastguard Worker			BuiltTool("sysprop_type_checker").
450*e4a36f41SAndroid Build Coastguard Worker			FlagForEachInput("--api ", apiFiles).
451*e4a36f41SAndroid Build Coastguard Worker			FlagWithInput("--context ", builtCtxFile).
452*e4a36f41SAndroid Build Coastguard Worker			Text(" || ( echo").Flag("-e").
453*e4a36f41SAndroid Build Coastguard Worker			Flag(`"` + msg + `"`).
454*e4a36f41SAndroid Build Coastguard Worker			Text("; exit 38) )")
455*e4a36f41SAndroid Build Coastguard Worker
456*e4a36f41SAndroid Build Coastguard Worker		rule.Command().Text("cp -f").Input(builtCtxFile).Output(out)
457*e4a36f41SAndroid Build Coastguard Worker		rule.Build("property_contexts_check_api", "checking API: "+m.Name())
458*e4a36f41SAndroid Build Coastguard Worker		builtCtxFile = out
459*e4a36f41SAndroid Build Coastguard Worker	}
460*e4a36f41SAndroid Build Coastguard Worker
461*e4a36f41SAndroid Build Coastguard Worker	return builtCtxFile
462*e4a36f41SAndroid Build Coastguard Worker}
463*e4a36f41SAndroid Build Coastguard Worker
464*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) shouldCheckCoredomain(ctx android.ModuleContext) bool {
465*e4a36f41SAndroid Build Coastguard Worker	if !ctx.SocSpecific() && !ctx.DeviceSpecific() {
466*e4a36f41SAndroid Build Coastguard Worker		return false
467*e4a36f41SAndroid Build Coastguard Worker	}
468*e4a36f41SAndroid Build Coastguard Worker
469*e4a36f41SAndroid Build Coastguard Worker	return ctx.DeviceConfig().CheckVendorSeappViolations()
470*e4a36f41SAndroid Build Coastguard Worker}
471*e4a36f41SAndroid Build Coastguard Worker
472*e4a36f41SAndroid Build Coastguard Workerfunc (m *selinuxContextsModule) buildSeappContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
473*e4a36f41SAndroid Build Coastguard Worker	neverallowFile := pathForModuleOut(ctx, "neverallow")
474*e4a36f41SAndroid Build Coastguard Worker	ret := pathForModuleOut(ctx, "checkseapp", m.stem())
475*e4a36f41SAndroid Build Coastguard Worker
476*e4a36f41SAndroid Build Coastguard Worker	// Step 1. Generate a M4 processed neverallow file
477*e4a36f41SAndroid Build Coastguard Worker	flags := m.getBuildFlags(ctx)
478*e4a36f41SAndroid Build Coastguard Worker	m4NeverallowFile := pathForModuleOut(ctx, "neverallow.m4out")
479*e4a36f41SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
480*e4a36f41SAndroid Build Coastguard Worker	rule.Command().
481*e4a36f41SAndroid Build Coastguard Worker		Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
482*e4a36f41SAndroid Build Coastguard Worker		Flag("--fatal-warnings").
483*e4a36f41SAndroid Build Coastguard Worker		FlagForEachArg("-D", ctx.DeviceConfig().SepolicyM4Defs()).
484*e4a36f41SAndroid Build Coastguard Worker		Flags(flagsToM4Macros(flags)).
485*e4a36f41SAndroid Build Coastguard Worker		Inputs(android.PathsForModuleSrc(ctx, m.seappProperties.Neverallow_files)).
486*e4a36f41SAndroid Build Coastguard Worker		FlagWithOutput("> ", m4NeverallowFile)
487*e4a36f41SAndroid Build Coastguard Worker
488*e4a36f41SAndroid Build Coastguard Worker	rule.Temporary(m4NeverallowFile)
489*e4a36f41SAndroid Build Coastguard Worker	rule.Command().
490*e4a36f41SAndroid Build Coastguard Worker		Text("( grep").
491*e4a36f41SAndroid Build Coastguard Worker		Flag("-ihe").
492*e4a36f41SAndroid Build Coastguard Worker		Text("'^neverallow'").
493*e4a36f41SAndroid Build Coastguard Worker		Input(m4NeverallowFile).
494*e4a36f41SAndroid Build Coastguard Worker		Text(">").
495*e4a36f41SAndroid Build Coastguard Worker		Output(neverallowFile).
496*e4a36f41SAndroid Build Coastguard Worker		Text("|| true )") // to make ninja happy even when result is empty
497*e4a36f41SAndroid Build Coastguard Worker
498*e4a36f41SAndroid Build Coastguard Worker	// Step 2. Generate a M4 processed contexts file
499*e4a36f41SAndroid Build Coastguard Worker	builtCtx := m.buildGeneralContexts(ctx, inputs)
500*e4a36f41SAndroid Build Coastguard Worker
501*e4a36f41SAndroid Build Coastguard Worker	// Step 3. checkseapp
502*e4a36f41SAndroid Build Coastguard Worker	rule.Temporary(neverallowFile)
503*e4a36f41SAndroid Build Coastguard Worker	checkCmd := rule.Command().BuiltTool("checkseapp").
504*e4a36f41SAndroid Build Coastguard Worker		FlagWithInput("-p ", android.PathForModuleSrc(ctx, proptools.String(m.seappProperties.Sepolicy))).
505*e4a36f41SAndroid Build Coastguard Worker		FlagWithOutput("-o ", ret).
506*e4a36f41SAndroid Build Coastguard Worker		Input(builtCtx).
507*e4a36f41SAndroid Build Coastguard Worker		Input(neverallowFile)
508*e4a36f41SAndroid Build Coastguard Worker
509*e4a36f41SAndroid Build Coastguard Worker	if m.shouldCheckCoredomain(ctx) {
510*e4a36f41SAndroid Build Coastguard Worker		checkCmd.Flag("-c") // check coredomain for vendor contexts
511*e4a36f41SAndroid Build Coastguard Worker	}
512*e4a36f41SAndroid Build Coastguard Worker
513*e4a36f41SAndroid Build Coastguard Worker	rule.Build("seapp_contexts", "Building seapp_contexts: "+m.Name())
514*e4a36f41SAndroid Build Coastguard Worker	return ret
515*e4a36f41SAndroid Build Coastguard Worker}
516*e4a36f41SAndroid Build Coastguard Worker
517*e4a36f41SAndroid Build Coastguard Workerfunc hwServiceFactory() android.Module {
518*e4a36f41SAndroid Build Coastguard Worker	m := newModule()
519*e4a36f41SAndroid Build Coastguard Worker	m.build = m.buildServiceContexts
520*e4a36f41SAndroid Build Coastguard Worker	return m
521*e4a36f41SAndroid Build Coastguard Worker}
522*e4a36f41SAndroid Build Coastguard Worker
523*e4a36f41SAndroid Build Coastguard Workerfunc propertyFactory() android.Module {
524*e4a36f41SAndroid Build Coastguard Worker	m := newModule()
525*e4a36f41SAndroid Build Coastguard Worker	m.build = m.buildPropertyContexts
526*e4a36f41SAndroid Build Coastguard Worker	m.deps = m.propertyContextsDeps
527*e4a36f41SAndroid Build Coastguard Worker	return m
528*e4a36f41SAndroid Build Coastguard Worker}
529*e4a36f41SAndroid Build Coastguard Worker
530*e4a36f41SAndroid Build Coastguard Workerfunc serviceFactory() android.Module {
531*e4a36f41SAndroid Build Coastguard Worker	m := newModule()
532*e4a36f41SAndroid Build Coastguard Worker	m.build = m.buildServiceContexts
533*e4a36f41SAndroid Build Coastguard Worker	return m
534*e4a36f41SAndroid Build Coastguard Worker}
535*e4a36f41SAndroid Build Coastguard Worker
536*e4a36f41SAndroid Build Coastguard Workerfunc keystoreKeyFactory() android.Module {
537*e4a36f41SAndroid Build Coastguard Worker	m := newModule()
538*e4a36f41SAndroid Build Coastguard Worker	m.build = m.buildGeneralContexts
539*e4a36f41SAndroid Build Coastguard Worker	return m
540*e4a36f41SAndroid Build Coastguard Worker}
541*e4a36f41SAndroid Build Coastguard Worker
542*e4a36f41SAndroid Build Coastguard Workerfunc teeServiceFactory() android.Module {
543*e4a36f41SAndroid Build Coastguard Worker	m := newModule()
544*e4a36f41SAndroid Build Coastguard Worker	m.build = m.buildGeneralContexts
545*e4a36f41SAndroid Build Coastguard Worker	return m
546*e4a36f41SAndroid Build Coastguard Worker}
547*e4a36f41SAndroid Build Coastguard Worker
548*e4a36f41SAndroid Build Coastguard Workerfunc seappFactory() android.Module {
549*e4a36f41SAndroid Build Coastguard Worker	m := newModule()
550*e4a36f41SAndroid Build Coastguard Worker	m.build = m.buildSeappContexts
551*e4a36f41SAndroid Build Coastguard Worker	return m
552*e4a36f41SAndroid Build Coastguard Worker}
553*e4a36f41SAndroid Build Coastguard Worker
554*e4a36f41SAndroid Build Coastguard Workerfunc vndServiceFactory() android.Module {
555*e4a36f41SAndroid Build Coastguard Worker	m := newModule()
556*e4a36f41SAndroid Build Coastguard Worker	m.build = m.buildGeneralContexts
557*e4a36f41SAndroid Build Coastguard Worker	android.AddLoadHook(m, func(ctx android.LoadHookContext) {
558*e4a36f41SAndroid Build Coastguard Worker		if !ctx.SocSpecific() {
559*e4a36f41SAndroid Build Coastguard Worker			ctx.ModuleErrorf(m.Name(), "must set vendor: true")
560*e4a36f41SAndroid Build Coastguard Worker			return
561*e4a36f41SAndroid Build Coastguard Worker		}
562*e4a36f41SAndroid Build Coastguard Worker	})
563*e4a36f41SAndroid Build Coastguard Worker	return m
564*e4a36f41SAndroid Build Coastguard Worker}
565*e4a36f41SAndroid Build Coastguard Worker
566*e4a36f41SAndroid Build Coastguard Workertype contextsTestProperties struct {
567*e4a36f41SAndroid Build Coastguard Worker	// Contexts files to be tested.
568*e4a36f41SAndroid Build Coastguard Worker	Srcs []string `android:"path"`
569*e4a36f41SAndroid Build Coastguard Worker
570*e4a36f41SAndroid Build Coastguard Worker	// Precompiled sepolicy binary to be tesed together.
571*e4a36f41SAndroid Build Coastguard Worker	Sepolicy *string `android:"path"`
572*e4a36f41SAndroid Build Coastguard Worker}
573*e4a36f41SAndroid Build Coastguard Worker
574*e4a36f41SAndroid Build Coastguard Workertype fileContextsTestProperties struct {
575*e4a36f41SAndroid Build Coastguard Worker	// Test data. File passed to `checkfc -t` to validate how contexts are resolved.
576*e4a36f41SAndroid Build Coastguard Worker	Test_data *string `android:"path"`
577*e4a36f41SAndroid Build Coastguard Worker}
578*e4a36f41SAndroid Build Coastguard Worker
579*e4a36f41SAndroid Build Coastguard Workertype contextsTestModule struct {
580*e4a36f41SAndroid Build Coastguard Worker	android.ModuleBase
581*e4a36f41SAndroid Build Coastguard Worker
582*e4a36f41SAndroid Build Coastguard Worker	// The type of context.
583*e4a36f41SAndroid Build Coastguard Worker	context contextType
584*e4a36f41SAndroid Build Coastguard Worker
585*e4a36f41SAndroid Build Coastguard Worker	properties     contextsTestProperties
586*e4a36f41SAndroid Build Coastguard Worker	fileProperties fileContextsTestProperties
587*e4a36f41SAndroid Build Coastguard Worker	testTimestamp  android.OutputPath
588*e4a36f41SAndroid Build Coastguard Worker}
589*e4a36f41SAndroid Build Coastguard Worker
590*e4a36f41SAndroid Build Coastguard Workertype contextType int
591*e4a36f41SAndroid Build Coastguard Worker
592*e4a36f41SAndroid Build Coastguard Workerconst (
593*e4a36f41SAndroid Build Coastguard Worker	FileContext contextType = iota
594*e4a36f41SAndroid Build Coastguard Worker	PropertyContext
595*e4a36f41SAndroid Build Coastguard Worker	ServiceContext
596*e4a36f41SAndroid Build Coastguard Worker	HwServiceContext
597*e4a36f41SAndroid Build Coastguard Worker	VndServiceContext
598*e4a36f41SAndroid Build Coastguard Worker)
599*e4a36f41SAndroid Build Coastguard Worker
600*e4a36f41SAndroid Build Coastguard Worker// checkfc parses a context file and checks for syntax errors.
601*e4a36f41SAndroid Build Coastguard Worker// If -s is specified, the service backend is used to verify binder services.
602*e4a36f41SAndroid Build Coastguard Worker// If -l is specified, the service backend is used to verify hwbinder services.
603*e4a36f41SAndroid Build Coastguard Worker// Otherwise, context_file is assumed to be a file_contexts file
604*e4a36f41SAndroid Build Coastguard Worker// If -e is specified, then the context_file is allowed to be empty.
605*e4a36f41SAndroid Build Coastguard Worker
606*e4a36f41SAndroid Build Coastguard Worker// file_contexts_test tests given file_contexts files with checkfc.
607*e4a36f41SAndroid Build Coastguard Workerfunc fileContextsTestFactory() android.Module {
608*e4a36f41SAndroid Build Coastguard Worker	m := &contextsTestModule{context: FileContext}
609*e4a36f41SAndroid Build Coastguard Worker	m.AddProperties(&m.properties)
610*e4a36f41SAndroid Build Coastguard Worker	m.AddProperties(&m.fileProperties)
611*e4a36f41SAndroid Build Coastguard Worker	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
612*e4a36f41SAndroid Build Coastguard Worker	return m
613*e4a36f41SAndroid Build Coastguard Worker}
614*e4a36f41SAndroid Build Coastguard Worker
615*e4a36f41SAndroid Build Coastguard Worker// property_contexts_test tests given property_contexts files with property_info_checker.
616*e4a36f41SAndroid Build Coastguard Workerfunc propertyContextsTestFactory() android.Module {
617*e4a36f41SAndroid Build Coastguard Worker	m := &contextsTestModule{context: PropertyContext}
618*e4a36f41SAndroid Build Coastguard Worker	m.AddProperties(&m.properties)
619*e4a36f41SAndroid Build Coastguard Worker	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
620*e4a36f41SAndroid Build Coastguard Worker	return m
621*e4a36f41SAndroid Build Coastguard Worker}
622*e4a36f41SAndroid Build Coastguard Worker
623*e4a36f41SAndroid Build Coastguard Worker// hwservice_contexts_test tests given hwservice_contexts files with checkfc.
624*e4a36f41SAndroid Build Coastguard Workerfunc hwserviceContextsTestFactory() android.Module {
625*e4a36f41SAndroid Build Coastguard Worker	m := &contextsTestModule{context: HwServiceContext}
626*e4a36f41SAndroid Build Coastguard Worker	m.AddProperties(&m.properties)
627*e4a36f41SAndroid Build Coastguard Worker	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
628*e4a36f41SAndroid Build Coastguard Worker	return m
629*e4a36f41SAndroid Build Coastguard Worker}
630*e4a36f41SAndroid Build Coastguard Worker
631*e4a36f41SAndroid Build Coastguard Worker// service_contexts_test tests given service_contexts files with checkfc.
632*e4a36f41SAndroid Build Coastguard Workerfunc serviceContextsTestFactory() android.Module {
633*e4a36f41SAndroid Build Coastguard Worker	// checkfc -s: service_contexts test
634*e4a36f41SAndroid Build Coastguard Worker	m := &contextsTestModule{context: ServiceContext}
635*e4a36f41SAndroid Build Coastguard Worker	m.AddProperties(&m.properties)
636*e4a36f41SAndroid Build Coastguard Worker	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
637*e4a36f41SAndroid Build Coastguard Worker	return m
638*e4a36f41SAndroid Build Coastguard Worker}
639*e4a36f41SAndroid Build Coastguard Worker
640*e4a36f41SAndroid Build Coastguard Worker// vndservice_contexts_test tests given vndservice_contexts files with checkfc.
641*e4a36f41SAndroid Build Coastguard Workerfunc vndServiceContextsTestFactory() android.Module {
642*e4a36f41SAndroid Build Coastguard Worker	m := &contextsTestModule{context: VndServiceContext}
643*e4a36f41SAndroid Build Coastguard Worker	m.AddProperties(&m.properties)
644*e4a36f41SAndroid Build Coastguard Worker	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
645*e4a36f41SAndroid Build Coastguard Worker	return m
646*e4a36f41SAndroid Build Coastguard Worker}
647*e4a36f41SAndroid Build Coastguard Worker
648*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
649*e4a36f41SAndroid Build Coastguard Worker	tool := "checkfc"
650*e4a36f41SAndroid Build Coastguard Worker	if m.context == PropertyContext {
651*e4a36f41SAndroid Build Coastguard Worker		tool = "property_info_checker"
652*e4a36f41SAndroid Build Coastguard Worker	}
653*e4a36f41SAndroid Build Coastguard Worker
654*e4a36f41SAndroid Build Coastguard Worker	if len(m.properties.Srcs) == 0 {
655*e4a36f41SAndroid Build Coastguard Worker		ctx.PropertyErrorf("srcs", "can't be empty")
656*e4a36f41SAndroid Build Coastguard Worker		return
657*e4a36f41SAndroid Build Coastguard Worker	}
658*e4a36f41SAndroid Build Coastguard Worker
659*e4a36f41SAndroid Build Coastguard Worker	validateWithPolicy := true
660*e4a36f41SAndroid Build Coastguard Worker	if proptools.String(m.properties.Sepolicy) == "" {
661*e4a36f41SAndroid Build Coastguard Worker		if m.context == FileContext {
662*e4a36f41SAndroid Build Coastguard Worker			if proptools.String(m.fileProperties.Test_data) == "" {
663*e4a36f41SAndroid Build Coastguard Worker				ctx.PropertyErrorf("test_data", "Either test_data or sepolicy should be provided")
664*e4a36f41SAndroid Build Coastguard Worker				return
665*e4a36f41SAndroid Build Coastguard Worker			}
666*e4a36f41SAndroid Build Coastguard Worker			validateWithPolicy = false
667*e4a36f41SAndroid Build Coastguard Worker		} else {
668*e4a36f41SAndroid Build Coastguard Worker			ctx.PropertyErrorf("sepolicy", "can't be empty")
669*e4a36f41SAndroid Build Coastguard Worker			return
670*e4a36f41SAndroid Build Coastguard Worker		}
671*e4a36f41SAndroid Build Coastguard Worker	}
672*e4a36f41SAndroid Build Coastguard Worker
673*e4a36f41SAndroid Build Coastguard Worker	flags := []string(nil)
674*e4a36f41SAndroid Build Coastguard Worker	switch m.context {
675*e4a36f41SAndroid Build Coastguard Worker	case FileContext:
676*e4a36f41SAndroid Build Coastguard Worker		if !validateWithPolicy {
677*e4a36f41SAndroid Build Coastguard Worker			flags = []string{"-t"}
678*e4a36f41SAndroid Build Coastguard Worker		}
679*e4a36f41SAndroid Build Coastguard Worker	case ServiceContext:
680*e4a36f41SAndroid Build Coastguard Worker		flags = []string{"-s" /* binder services */}
681*e4a36f41SAndroid Build Coastguard Worker	case HwServiceContext:
682*e4a36f41SAndroid Build Coastguard Worker		flags = []string{"-e" /* allow empty */, "-l" /* hwbinder services */}
683*e4a36f41SAndroid Build Coastguard Worker	case VndServiceContext:
684*e4a36f41SAndroid Build Coastguard Worker		flags = []string{"-e" /* allow empty */, "-v" /* vnd service */}
685*e4a36f41SAndroid Build Coastguard Worker	}
686*e4a36f41SAndroid Build Coastguard Worker
687*e4a36f41SAndroid Build Coastguard Worker	srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs)
688*e4a36f41SAndroid Build Coastguard Worker	rule := android.NewRuleBuilder(pctx, ctx)
689*e4a36f41SAndroid Build Coastguard Worker
690*e4a36f41SAndroid Build Coastguard Worker	if validateWithPolicy {
691*e4a36f41SAndroid Build Coastguard Worker		sepolicy := android.PathForModuleSrc(ctx, proptools.String(m.properties.Sepolicy))
692*e4a36f41SAndroid Build Coastguard Worker		rule.Command().BuiltTool(tool).
693*e4a36f41SAndroid Build Coastguard Worker			Flags(flags).
694*e4a36f41SAndroid Build Coastguard Worker			Input(sepolicy).
695*e4a36f41SAndroid Build Coastguard Worker			Inputs(srcs)
696*e4a36f41SAndroid Build Coastguard Worker	} else {
697*e4a36f41SAndroid Build Coastguard Worker		test_data := android.PathForModuleSrc(ctx, proptools.String(m.fileProperties.Test_data))
698*e4a36f41SAndroid Build Coastguard Worker		rule.Command().BuiltTool(tool).
699*e4a36f41SAndroid Build Coastguard Worker			Flags(flags).
700*e4a36f41SAndroid Build Coastguard Worker			Inputs(srcs).
701*e4a36f41SAndroid Build Coastguard Worker			Input(test_data)
702*e4a36f41SAndroid Build Coastguard Worker	}
703*e4a36f41SAndroid Build Coastguard Worker
704*e4a36f41SAndroid Build Coastguard Worker	m.testTimestamp = pathForModuleOut(ctx, "timestamp")
705*e4a36f41SAndroid Build Coastguard Worker	rule.Command().Text("touch").Output(m.testTimestamp)
706*e4a36f41SAndroid Build Coastguard Worker	rule.Build("contexts_test", "running contexts test: "+ctx.ModuleName())
707*e4a36f41SAndroid Build Coastguard Worker}
708*e4a36f41SAndroid Build Coastguard Worker
709*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) AndroidMkEntries() []android.AndroidMkEntries {
710*e4a36f41SAndroid Build Coastguard Worker	return []android.AndroidMkEntries{android.AndroidMkEntries{
711*e4a36f41SAndroid Build Coastguard Worker		Class: "FAKE",
712*e4a36f41SAndroid Build Coastguard Worker		// OutputFile is needed, even though BUILD_PHONY_PACKAGE doesn't use it.
713*e4a36f41SAndroid Build Coastguard Worker		// Without OutputFile this module won't be exported to Makefile.
714*e4a36f41SAndroid Build Coastguard Worker		OutputFile: android.OptionalPathForPath(m.testTimestamp),
715*e4a36f41SAndroid Build Coastguard Worker		Include:    "$(BUILD_PHONY_PACKAGE)",
716*e4a36f41SAndroid Build Coastguard Worker		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
717*e4a36f41SAndroid Build Coastguard Worker			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
718*e4a36f41SAndroid Build Coastguard Worker				entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", m.testTimestamp.String())
719*e4a36f41SAndroid Build Coastguard Worker			},
720*e4a36f41SAndroid Build Coastguard Worker		},
721*e4a36f41SAndroid Build Coastguard Worker	}}
722*e4a36f41SAndroid Build Coastguard Worker}
723*e4a36f41SAndroid Build Coastguard Worker
724*e4a36f41SAndroid Build Coastguard Worker// contextsTestModule implements ImageInterface to be able to include recovery_available contexts
725*e4a36f41SAndroid Build Coastguard Worker// modules as its sources.
726*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) ImageMutatorBegin(ctx android.ImageInterfaceContext) {
727*e4a36f41SAndroid Build Coastguard Worker}
728*e4a36f41SAndroid Build Coastguard Worker
729*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
730*e4a36f41SAndroid Build Coastguard Worker	return false
731*e4a36f41SAndroid Build Coastguard Worker}
732*e4a36f41SAndroid Build Coastguard Worker
733*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
734*e4a36f41SAndroid Build Coastguard Worker	return false
735*e4a36f41SAndroid Build Coastguard Worker}
736*e4a36f41SAndroid Build Coastguard Worker
737*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
738*e4a36f41SAndroid Build Coastguard Worker	return true
739*e4a36f41SAndroid Build Coastguard Worker}
740*e4a36f41SAndroid Build Coastguard Worker
741*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
742*e4a36f41SAndroid Build Coastguard Worker	return false
743*e4a36f41SAndroid Build Coastguard Worker}
744*e4a36f41SAndroid Build Coastguard Worker
745*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
746*e4a36f41SAndroid Build Coastguard Worker	return false
747*e4a36f41SAndroid Build Coastguard Worker}
748*e4a36f41SAndroid Build Coastguard Worker
749*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
750*e4a36f41SAndroid Build Coastguard Worker	return false
751*e4a36f41SAndroid Build Coastguard Worker}
752*e4a36f41SAndroid Build Coastguard Worker
753*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
754*e4a36f41SAndroid Build Coastguard Worker	return false
755*e4a36f41SAndroid Build Coastguard Worker}
756*e4a36f41SAndroid Build Coastguard Worker
757*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
758*e4a36f41SAndroid Build Coastguard Worker	return nil
759*e4a36f41SAndroid Build Coastguard Worker}
760*e4a36f41SAndroid Build Coastguard Worker
761*e4a36f41SAndroid Build Coastguard Workerfunc (m *contextsTestModule) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
762*e4a36f41SAndroid Build Coastguard Worker}
763*e4a36f41SAndroid Build Coastguard Worker
764*e4a36f41SAndroid Build Coastguard Workervar _ android.ImageInterface = (*contextsTestModule)(nil)
765