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