1*e4a36f41SAndroid Build Coastguard Worker// Copyright (C) 2018 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 Worker// This file contains "se_cil_compat_map" module type used to build and install 18*e4a36f41SAndroid Build Coastguard Worker// sepolicy backwards compatibility mapping files. 19*e4a36f41SAndroid Build Coastguard Worker 20*e4a36f41SAndroid Build Coastguard Workerimport ( 21*e4a36f41SAndroid Build Coastguard Worker "android/soong/android" 22*e4a36f41SAndroid Build Coastguard Worker 23*e4a36f41SAndroid Build Coastguard Worker "github.com/google/blueprint" 24*e4a36f41SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 25*e4a36f41SAndroid Build Coastguard Worker) 26*e4a36f41SAndroid Build Coastguard Worker 27*e4a36f41SAndroid Build Coastguard Workervar ( 28*e4a36f41SAndroid Build Coastguard Worker combine_maps = pctx.HostBinToolVariable("combine_maps", "combine_maps") 29*e4a36f41SAndroid Build Coastguard Worker combineMapsCmd = "${combine_maps} -t ${topHalf} -b ${bottomHalf} -o $out" 30*e4a36f41SAndroid Build Coastguard Worker combineMapsRule = pctx.StaticRule( 31*e4a36f41SAndroid Build Coastguard Worker "combineMapsRule", 32*e4a36f41SAndroid Build Coastguard Worker blueprint.RuleParams{ 33*e4a36f41SAndroid Build Coastguard Worker Command: combineMapsCmd, 34*e4a36f41SAndroid Build Coastguard Worker CommandDeps: []string{"${combine_maps}"}, 35*e4a36f41SAndroid Build Coastguard Worker }, 36*e4a36f41SAndroid Build Coastguard Worker "topHalf", 37*e4a36f41SAndroid Build Coastguard Worker "bottomHalf", 38*e4a36f41SAndroid Build Coastguard Worker ) 39*e4a36f41SAndroid Build Coastguard Worker 40*e4a36f41SAndroid Build Coastguard Worker String = proptools.String 41*e4a36f41SAndroid Build Coastguard Worker TopHalfDepTag = dependencyTag{name: "top"} 42*e4a36f41SAndroid Build Coastguard Worker) 43*e4a36f41SAndroid Build Coastguard Worker 44*e4a36f41SAndroid Build Coastguard Workerfunc init() { 45*e4a36f41SAndroid Build Coastguard Worker android.RegisterModuleType("se_cil_compat_map", cilCompatMapFactory) 46*e4a36f41SAndroid Build Coastguard Worker pctx.Import("android/soong/android") 47*e4a36f41SAndroid Build Coastguard Worker} 48*e4a36f41SAndroid Build Coastguard Worker 49*e4a36f41SAndroid Build Coastguard Workerfunc cilCompatMapFactory() android.Module { 50*e4a36f41SAndroid Build Coastguard Worker c := &cilCompatMap{} 51*e4a36f41SAndroid Build Coastguard Worker c.AddProperties(&c.properties) 52*e4a36f41SAndroid Build Coastguard Worker android.InitAndroidArchModule(c, android.DeviceSupported, android.MultilibCommon) 53*e4a36f41SAndroid Build Coastguard Worker return c 54*e4a36f41SAndroid Build Coastguard Worker} 55*e4a36f41SAndroid Build Coastguard Worker 56*e4a36f41SAndroid Build Coastguard Workertype cilCompatMapProperties struct { 57*e4a36f41SAndroid Build Coastguard Worker // se_cil_compat_map module representing a compatibility mapping file for 58*e4a36f41SAndroid Build Coastguard Worker // platform versions (x->y). Bottom half represents a mapping (y->z). 59*e4a36f41SAndroid Build Coastguard Worker // Together the halves are used to generate a (x->z) mapping. 60*e4a36f41SAndroid Build Coastguard Worker Top_half *string `android:"path"` 61*e4a36f41SAndroid Build Coastguard Worker // list of source (.cil) files used to build an the bottom half of sepolicy 62*e4a36f41SAndroid Build Coastguard Worker // compatibility mapping file. bottom_half may reference the outputs of 63*e4a36f41SAndroid Build Coastguard Worker // other modules that produce source files like genrule or filegroup using 64*e4a36f41SAndroid Build Coastguard Worker // the syntax ":module". srcs has to be non-empty. 65*e4a36f41SAndroid Build Coastguard Worker Bottom_half []string `android:"path"` 66*e4a36f41SAndroid Build Coastguard Worker // name of the output 67*e4a36f41SAndroid Build Coastguard Worker Stem *string 68*e4a36f41SAndroid Build Coastguard Worker // Target version that this module supports. This module will be ignored if platform sepolicy 69*e4a36f41SAndroid Build Coastguard Worker // version is same as this module's version. 70*e4a36f41SAndroid Build Coastguard Worker Version *string 71*e4a36f41SAndroid Build Coastguard Worker} 72*e4a36f41SAndroid Build Coastguard Worker 73*e4a36f41SAndroid Build Coastguard Workertype cilCompatMap struct { 74*e4a36f41SAndroid Build Coastguard Worker android.ModuleBase 75*e4a36f41SAndroid Build Coastguard Worker properties cilCompatMapProperties 76*e4a36f41SAndroid Build Coastguard Worker // (.intermediate) module output path as installation source. 77*e4a36f41SAndroid Build Coastguard Worker installSource android.OptionalPath 78*e4a36f41SAndroid Build Coastguard Worker installPath android.InstallPath 79*e4a36f41SAndroid Build Coastguard Worker} 80*e4a36f41SAndroid Build Coastguard Worker 81*e4a36f41SAndroid Build Coastguard Workertype CilCompatMapGenerator interface { 82*e4a36f41SAndroid Build Coastguard Worker GeneratedMapFile() android.OptionalPath 83*e4a36f41SAndroid Build Coastguard Worker} 84*e4a36f41SAndroid Build Coastguard Worker 85*e4a36f41SAndroid Build Coastguard Workerfunc expandTopHalf(ctx android.ModuleContext) android.OptionalPath { 86*e4a36f41SAndroid Build Coastguard Worker var topHalf android.OptionalPath 87*e4a36f41SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(dep android.Module) { 88*e4a36f41SAndroid Build Coastguard Worker depTag := ctx.OtherModuleDependencyTag(dep) 89*e4a36f41SAndroid Build Coastguard Worker switch depTag { 90*e4a36f41SAndroid Build Coastguard Worker case TopHalfDepTag: 91*e4a36f41SAndroid Build Coastguard Worker topHalf = dep.(CilCompatMapGenerator).GeneratedMapFile() 92*e4a36f41SAndroid Build Coastguard Worker } 93*e4a36f41SAndroid Build Coastguard Worker }) 94*e4a36f41SAndroid Build Coastguard Worker return topHalf 95*e4a36f41SAndroid Build Coastguard Worker} 96*e4a36f41SAndroid Build Coastguard Worker 97*e4a36f41SAndroid Build Coastguard Workerfunc expandSeSources(ctx android.ModuleContext, srcFiles []string) android.Paths { 98*e4a36f41SAndroid Build Coastguard Worker return android.PathsForModuleSrc(ctx, srcFiles) 99*e4a36f41SAndroid Build Coastguard Worker} 100*e4a36f41SAndroid Build Coastguard Worker 101*e4a36f41SAndroid Build Coastguard Workerfunc (c *cilCompatMap) shouldSkipBuild(ctx android.ModuleContext) bool { 102*e4a36f41SAndroid Build Coastguard Worker return proptools.String(c.properties.Version) == ctx.DeviceConfig().PlatformSepolicyVersion() 103*e4a36f41SAndroid Build Coastguard Worker} 104*e4a36f41SAndroid Build Coastguard Worker 105*e4a36f41SAndroid Build Coastguard Workerfunc (c *cilCompatMap) stem() string { 106*e4a36f41SAndroid Build Coastguard Worker return proptools.StringDefault(c.properties.Stem, c.Name()) 107*e4a36f41SAndroid Build Coastguard Worker} 108*e4a36f41SAndroid Build Coastguard Worker 109*e4a36f41SAndroid Build Coastguard Workerfunc (c *cilCompatMap) GenerateAndroidBuildActions(ctx android.ModuleContext) { 110*e4a36f41SAndroid Build Coastguard Worker if c.shouldSkipBuild(ctx) { 111*e4a36f41SAndroid Build Coastguard Worker return 112*e4a36f41SAndroid Build Coastguard Worker } 113*e4a36f41SAndroid Build Coastguard Worker 114*e4a36f41SAndroid Build Coastguard Worker c.installPath = android.PathForModuleInstall(ctx, "etc", "selinux", "mapping") 115*e4a36f41SAndroid Build Coastguard Worker 116*e4a36f41SAndroid Build Coastguard Worker srcFiles := expandSeSources(ctx, c.properties.Bottom_half) 117*e4a36f41SAndroid Build Coastguard Worker 118*e4a36f41SAndroid Build Coastguard Worker for _, src := range srcFiles { 119*e4a36f41SAndroid Build Coastguard Worker if src.Ext() != ".cil" { 120*e4a36f41SAndroid Build Coastguard Worker ctx.PropertyErrorf("bottom_half", "%s has to be a .cil file.", src.String()) 121*e4a36f41SAndroid Build Coastguard Worker } 122*e4a36f41SAndroid Build Coastguard Worker } 123*e4a36f41SAndroid Build Coastguard Worker 124*e4a36f41SAndroid Build Coastguard Worker bottomHalf := android.PathForModuleGen(ctx, "bottom_half") 125*e4a36f41SAndroid Build Coastguard Worker ctx.Build(pctx, android.BuildParams{ 126*e4a36f41SAndroid Build Coastguard Worker Rule: android.Cat, 127*e4a36f41SAndroid Build Coastguard Worker Output: bottomHalf, 128*e4a36f41SAndroid Build Coastguard Worker Inputs: srcFiles, 129*e4a36f41SAndroid Build Coastguard Worker }) 130*e4a36f41SAndroid Build Coastguard Worker 131*e4a36f41SAndroid Build Coastguard Worker topHalf := expandTopHalf(ctx) 132*e4a36f41SAndroid Build Coastguard Worker if topHalf.Valid() { 133*e4a36f41SAndroid Build Coastguard Worker out := android.PathForModuleGen(ctx, c.Name()) 134*e4a36f41SAndroid Build Coastguard Worker ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 135*e4a36f41SAndroid Build Coastguard Worker Rule: combineMapsRule, 136*e4a36f41SAndroid Build Coastguard Worker Output: out, 137*e4a36f41SAndroid Build Coastguard Worker Implicits: []android.Path{ 138*e4a36f41SAndroid Build Coastguard Worker topHalf.Path(), 139*e4a36f41SAndroid Build Coastguard Worker bottomHalf, 140*e4a36f41SAndroid Build Coastguard Worker }, 141*e4a36f41SAndroid Build Coastguard Worker Args: map[string]string{ 142*e4a36f41SAndroid Build Coastguard Worker "topHalf": topHalf.String(), 143*e4a36f41SAndroid Build Coastguard Worker "bottomHalf": bottomHalf.String(), 144*e4a36f41SAndroid Build Coastguard Worker }, 145*e4a36f41SAndroid Build Coastguard Worker }) 146*e4a36f41SAndroid Build Coastguard Worker c.installSource = android.OptionalPathForPath(out) 147*e4a36f41SAndroid Build Coastguard Worker } else { 148*e4a36f41SAndroid Build Coastguard Worker c.installSource = android.OptionalPathForPath(bottomHalf) 149*e4a36f41SAndroid Build Coastguard Worker } 150*e4a36f41SAndroid Build Coastguard Worker ctx.InstallFile(c.installPath, c.stem(), c.installSource.Path()) 151*e4a36f41SAndroid Build Coastguard Worker 152*e4a36f41SAndroid Build Coastguard Worker if c.installSource.Valid() { 153*e4a36f41SAndroid Build Coastguard Worker ctx.SetOutputFiles(android.Paths{c.installSource.Path()}, "") 154*e4a36f41SAndroid Build Coastguard Worker } 155*e4a36f41SAndroid Build Coastguard Worker} 156*e4a36f41SAndroid Build Coastguard Worker 157*e4a36f41SAndroid Build Coastguard Workerfunc (c *cilCompatMap) DepsMutator(ctx android.BottomUpMutatorContext) { 158*e4a36f41SAndroid Build Coastguard Worker if c.properties.Top_half != nil { 159*e4a36f41SAndroid Build Coastguard Worker ctx.AddDependency(c, TopHalfDepTag, String(c.properties.Top_half)) 160*e4a36f41SAndroid Build Coastguard Worker } 161*e4a36f41SAndroid Build Coastguard Worker} 162*e4a36f41SAndroid Build Coastguard Worker 163*e4a36f41SAndroid Build Coastguard Workerfunc (c *cilCompatMap) AndroidMkEntries() []android.AndroidMkEntries { 164*e4a36f41SAndroid Build Coastguard Worker if !c.installSource.Valid() { 165*e4a36f41SAndroid Build Coastguard Worker return nil 166*e4a36f41SAndroid Build Coastguard Worker } 167*e4a36f41SAndroid Build Coastguard Worker return []android.AndroidMkEntries{android.AndroidMkEntries{ 168*e4a36f41SAndroid Build Coastguard Worker Class: "ETC", 169*e4a36f41SAndroid Build Coastguard Worker OutputFile: c.installSource, 170*e4a36f41SAndroid Build Coastguard Worker ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 171*e4a36f41SAndroid Build Coastguard Worker func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { 172*e4a36f41SAndroid Build Coastguard Worker entries.SetPath("LOCAL_MODULE_PATH", c.installPath) 173*e4a36f41SAndroid Build Coastguard Worker if c.properties.Stem != nil { 174*e4a36f41SAndroid Build Coastguard Worker entries.SetString("LOCAL_INSTALLED_MODULE_STEM", String(c.properties.Stem)) 175*e4a36f41SAndroid Build Coastguard Worker } 176*e4a36f41SAndroid Build Coastguard Worker }, 177*e4a36f41SAndroid Build Coastguard Worker }, 178*e4a36f41SAndroid Build Coastguard Worker }} 179*e4a36f41SAndroid Build Coastguard Worker} 180*e4a36f41SAndroid Build Coastguard Worker 181*e4a36f41SAndroid Build Coastguard Workervar _ CilCompatMapGenerator = (*cilCompatMap)(nil) 182*e4a36f41SAndroid Build Coastguard Worker 183*e4a36f41SAndroid Build Coastguard Workerfunc (c *cilCompatMap) GeneratedMapFile() android.OptionalPath { 184*e4a36f41SAndroid Build Coastguard Worker return c.installSource 185*e4a36f41SAndroid Build Coastguard Worker} 186