1// Copyright (C) 2021 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package selinux 16 17import ( 18 "os" 19 "strconv" 20 21 "github.com/google/blueprint/proptools" 22 23 "android/soong/android" 24) 25 26func init() { 27 android.RegisterModuleType("se_versioned_policy", versionedPolicyFactory) 28} 29 30type versionedPolicyProperties struct { 31 // Base cil file for versioning. 32 Base *string `android:"path"` 33 34 // Output file name. Defaults to {name} if target_policy is set, {version}.cil if mapping is set 35 Stem *string 36 37 // Target sepolicy version. Can be a specific version number (e.g. "30.0" for R), "current" 38 // (PLATFORM_SEPOLICY_VERSION), or "vendor" (BOARD_SEPOLICY_VERS). Defaults to "current" 39 Version *string 40 41 // If true, generate mapping file from given base cil file. Cannot be set with target_policy. 42 Mapping *bool 43 44 // If given, version target policy file according to base policy. Cannot be set with mapping. 45 Target_policy *string `android:"path"` 46 47 // Cil files to be filtered out by the filter_out tool of "build_sepolicy". 48 Filter_out []string `android:"path"` 49 50 // Cil files to which this mapping file depends. If specified, secilc checks whether the output 51 // file can be merged with specified cil files or not. 52 Dependent_cils []string `android:"path"` 53 54 // Whether this module is directly installable to one of the partitions. Default is true 55 Installable *bool 56 57 // install to a subdirectory of the default install path for the module 58 Relative_install_path *string 59} 60 61type versionedPolicy struct { 62 android.ModuleBase 63 64 properties versionedPolicyProperties 65 66 installSource android.Path 67 installPath android.InstallPath 68} 69 70// se_versioned_policy generates versioned cil file with "version_policy". This can generate either 71// mapping file for public plat policies, or associate a target policy file with the version that 72// non-platform policy targets. 73func versionedPolicyFactory() android.Module { 74 m := &versionedPolicy{} 75 m.AddProperties(&m.properties) 76 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon) 77 return m 78} 79 80func (m *versionedPolicy) installable() bool { 81 return proptools.BoolDefault(m.properties.Installable, true) 82} 83 84func (m *versionedPolicy) DepsMutator(ctx android.BottomUpMutatorContext) { 85 // do nothing 86} 87 88func (m *versionedPolicy) GenerateAndroidBuildActions(ctx android.ModuleContext) { 89 version := proptools.StringDefault(m.properties.Version, "current") 90 if version == "current" { 91 version = ctx.DeviceConfig().PlatformSepolicyVersion() 92 } else if version == "vendor" { 93 version = ctx.DeviceConfig().BoardSepolicyVers() 94 } 95 96 var stem string 97 if s := proptools.String(m.properties.Stem); s != "" { 98 stem = s 99 } else if proptools.Bool(m.properties.Mapping) { 100 stem = version + ".cil" 101 } else { 102 stem = ctx.ModuleName() 103 } 104 105 out := pathForModuleOut(ctx, stem) 106 rule := android.NewRuleBuilder(pctx, ctx) 107 108 if proptools.String(m.properties.Base) == "" { 109 ctx.PropertyErrorf("base", "must be specified") 110 return 111 } 112 113 versionCmd := rule.Command().BuiltTool("version_policy"). 114 FlagWithInput("-b ", android.PathForModuleSrc(ctx, *m.properties.Base)). 115 FlagWithArg("-n ", version). 116 FlagWithOutput("-o ", out) 117 118 if proptools.Bool(m.properties.Mapping) && proptools.String(m.properties.Target_policy) != "" { 119 ctx.ModuleErrorf("Can't set both mapping and target_policy") 120 return 121 } 122 123 if proptools.Bool(m.properties.Mapping) { 124 versionCmd.Flag("-m") 125 } else if target := proptools.String(m.properties.Target_policy); target != "" { 126 versionCmd.FlagWithInput("-t ", android.PathForModuleSrc(ctx, target)) 127 } else { 128 ctx.ModuleErrorf("Either mapping or target_policy must be set") 129 return 130 } 131 132 if len(m.properties.Filter_out) > 0 { 133 rule.Command().BuiltTool("build_sepolicy"). 134 Text("filter_out"). 135 Flag("-f"). 136 Inputs(android.PathsForModuleSrc(ctx, m.properties.Filter_out)). 137 FlagWithOutput("-t ", out) 138 } 139 140 if len(m.properties.Dependent_cils) > 0 { 141 rule.Command().BuiltTool("secilc"). 142 Flag("-m"). 143 FlagWithArg("-M ", "true"). 144 Flag("-G"). 145 Flag("-N"). 146 FlagWithArg("-c ", strconv.Itoa(PolicyVers)). 147 Inputs(android.PathsForModuleSrc(ctx, m.properties.Dependent_cils)). 148 Text(out.String()). 149 FlagWithArg("-o ", os.DevNull). 150 FlagWithArg("-f ", os.DevNull) 151 } 152 153 rule.Build("mapping", "Versioning mapping file "+ctx.ModuleName()) 154 155 if !m.installable() { 156 m.SkipInstall() 157 } 158 159 m.installSource = out 160 m.installPath = android.PathForModuleInstall(ctx, "etc", "selinux") 161 if subdir := proptools.String(m.properties.Relative_install_path); subdir != "" { 162 m.installPath = m.installPath.Join(ctx, subdir) 163 } 164 ctx.InstallFile(m.installPath, m.installSource.Base(), m.installSource) 165 166 ctx.SetOutputFiles(android.Paths{m.installSource}, "") 167} 168 169func (m *versionedPolicy) AndroidMkEntries() []android.AndroidMkEntries { 170 return []android.AndroidMkEntries{android.AndroidMkEntries{ 171 OutputFile: android.OptionalPathForPath(m.installSource), 172 Class: "ETC", 173 ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 174 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { 175 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !m.installable()) 176 entries.SetPath("LOCAL_MODULE_PATH", m.installPath) 177 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", m.installSource.Base()) 178 }, 179 }, 180 }} 181} 182