Add macros to flag-guard te and contexts files

This adds two macros which can be used in te files and contexts files.

* is_flag_enabled(flag_name, codes)
* is_flag_disabled(flag_name, codes)

Also flag-guarding requires to process input files before any
validations. Property contexts test and seapp contexts test are
modified a little to handle that.

Bug: 306563735
Test: build with manual guarding
Change-Id: Ia1c6d00b7aab0da3901c19f16d553153aace018c
This commit is contained in:
Inseob Kim 2023-11-09 11:13:01 +09:00
parent 6cd0dddf1f
commit 085f22f82d
9 changed files with 154 additions and 27 deletions

View file

@ -103,6 +103,7 @@ product_private_policy = [":se_build_files{.product_private}"]
// policy and subsequent removal of CIL policy that should not be exported.
se_policy_conf {
name: "reqd_policy_mask.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: reqd_mask_policy,
installable: false,
}
@ -138,6 +139,7 @@ se_policy_cil {
//
se_policy_conf {
name: "pub_policy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
system_ext_public_policy +
product_public_policy +
@ -157,6 +159,7 @@ se_policy_cil {
se_policy_conf {
name: "system_ext_pub_policy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
system_ext_public_policy +
reqd_mask_policy,
@ -175,6 +178,7 @@ se_policy_cil {
se_policy_conf {
name: "plat_pub_policy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
reqd_mask_policy,
installable: false,
@ -195,6 +199,7 @@ se_policy_cil {
// currently being attributized.
se_policy_conf {
name: "plat_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy,
installable: false,
@ -210,6 +215,7 @@ se_policy_cil {
// userdebug_plat_policy.conf - the userdebug version plat_sepolicy.cil
se_policy_conf {
name: "userdebug_plat_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy,
build_variant: "userdebug",
@ -260,6 +266,7 @@ gsi_se_policy_cil {
// policy which will ship with the device. System_ext policy is not attributized
se_policy_conf {
name: "system_ext_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy +
system_ext_public_policy +
@ -280,6 +287,7 @@ se_policy_cil {
// which will ship with the device. Product policy is not attributized
se_policy_conf {
name: "product_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy +
system_ext_public_policy +
@ -348,6 +356,7 @@ se_versioned_policy {
// policy and the platform public policy files in order to use checkpolicy.
se_policy_conf {
name: "vendor_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
system_ext_public_policy +
product_public_policy +
@ -389,6 +398,7 @@ se_versioned_policy {
// policy and the platform public policy files in order to use checkpolicy.
se_policy_conf {
name: "odm_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
system_ext_public_policy +
product_public_policy +
@ -598,6 +608,7 @@ precompiled_se_policy_binary {
// policy for recovery
se_policy_conf {
name: "recovery_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy +
system_ext_public_policy +
@ -634,6 +645,7 @@ se_policy_binary {
//////////////////////////////////
se_policy_conf {
name: "general_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy,
build_variant: "user",
@ -650,6 +662,7 @@ se_policy_conf {
//////////////////////////////////
se_policy_conf {
name: "base_plat_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy,
build_variant: "user",
@ -675,6 +688,7 @@ se_policy_binary {
se_policy_conf {
name: "base_product_sepolicy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy +
system_ext_public_policy +
@ -704,6 +718,7 @@ se_policy_binary {
se_policy_conf {
name: "base_plat_pub_policy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
reqd_mask_policy,
build_variant: "user",
@ -723,6 +738,7 @@ se_policy_cil {
se_policy_conf {
name: "base_product_pub_policy.conf",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
system_ext_public_policy +
product_public_policy +
@ -770,6 +786,7 @@ se_bug_map {
se_neverallow_test {
name: "sepolicy_neverallows",
defaults: ["se_policy_conf_flags_defaults"],
srcs: plat_public_policy +
plat_private_policy +
system_ext_public_policy +

View file

@ -129,6 +129,7 @@ var _ android.OutputFileProducer = (*compatCil)(nil)
// current policy.
func compatTestFactory() android.SingletonModule {
f := &compatTestModule{}
f.AddProperties(&f.properties)
android.InitAndroidModule(f)
android.AddLoadHook(f, func(ctx android.LoadHookContext) {
f.loadHook(ctx)
@ -138,6 +139,10 @@ func compatTestFactory() android.SingletonModule {
type compatTestModule struct {
android.SingletonModuleBase
properties struct {
// Default modules for conf
Defaults []string
}
compatTestTimestamp android.ModuleOutPath
}
@ -157,6 +162,10 @@ func (f *compatTestModule) createPlatPubVersionedModule(ctx android.LoadHookCont
":se_build_files{.reqd_mask}",
},
Installable: proptools.BoolPtr(false),
}, &struct {
Defaults []string
}{
Defaults: f.properties.Defaults,
})
ctx.CreateModule(policyCilFactory, &nameProperties{

View file

@ -17,7 +17,6 @@ package selinux
import (
"fmt"
"io"
"os"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@ -338,7 +337,7 @@ func (m *selinuxContextsModule) buildServiceContexts(ctx android.ModuleContext,
return m.buildGeneralContexts(ctx, inputs)
}
func (m *selinuxContextsModule) checkVendorPropertyNamespace(ctx android.ModuleContext, inputs android.Paths) android.Paths {
func (m *selinuxContextsModule) checkVendorPropertyNamespace(ctx android.ModuleContext, input android.Path) android.Path {
shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
ApiLevelR := android.ApiLevelOrPanic(ctx, "R")
@ -379,37 +378,33 @@ func (m *selinuxContextsModule) checkVendorPropertyNamespace(ctx android.ModuleC
}
}
var ret android.Paths
for _, input := range inputs {
cmd := rule.Command().
BuiltTool("check_prop_prefix").
FlagWithInput("--property-contexts ", input).
FlagForEachArg("--allowed-property-prefix ", proptools.ShellEscapeList(allowedPropertyPrefixes)). // contains shell special character '$'
FlagForEachArg("--allowed-context-prefix ", allowedContextPrefixes)
cmd := rule.Command().
BuiltTool("check_prop_prefix").
FlagWithInput("--property-contexts ", input).
FlagForEachArg("--allowed-property-prefix ", proptools.ShellEscapeList(allowedPropertyPrefixes)). // contains shell special character '$'
FlagForEachArg("--allowed-context-prefix ", allowedContextPrefixes)
if !ctx.DeviceConfig().BuildBrokenVendorPropertyNamespace() {
cmd.Flag("--strict")
}
out := pathForModuleOut(ctx, "namespace_checked").Join(ctx, input.String())
rule.Command().Text("cp -f").Input(input).Output(out)
ret = append(ret, out)
if !ctx.DeviceConfig().BuildBrokenVendorPropertyNamespace() {
cmd.Flag("--strict")
}
out := pathForModuleOut(ctx, "namespace_checked").Join(ctx, input.String())
rule.Command().Text("cp -f").Input(input).Output(out)
rule.Build("check_namespace", "checking namespace of "+ctx.ModuleName())
return ret
return out
}
func (m *selinuxContextsModule) buildPropertyContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
// vendor/odm properties are enforced for devices launching with Android Q or later. So, if
// vendor/odm, make sure that only vendor/odm properties exist.
builtCtxFile := m.buildGeneralContexts(ctx, inputs)
shippingApiLevel := ctx.DeviceConfig().ShippingApiLevel()
ApiLevelQ := android.ApiLevelOrPanic(ctx, "Q")
if (ctx.SocSpecific() || ctx.DeviceSpecific()) && shippingApiLevel.GreaterThanOrEqualTo(ApiLevelQ) {
inputs = m.checkVendorPropertyNamespace(ctx, inputs)
builtCtxFile = m.checkVendorPropertyNamespace(ctx, builtCtxFile)
}
builtCtxFile := m.buildGeneralContexts(ctx, inputs)
var apiFiles android.Paths
ctx.VisitDirectDepsWithTag(syspropLibraryDepTag, func(c android.Module) {
i, ok := c.(interface{ CurrentSyspropApiFile() android.OptionalPath })
@ -458,23 +453,39 @@ func (m *selinuxContextsModule) shouldCheckCoredomain(ctx android.ModuleContext)
func (m *selinuxContextsModule) buildSeappContexts(ctx android.ModuleContext, inputs android.Paths) android.Path {
neverallowFile := pathForModuleOut(ctx, "neverallow")
ret := pathForModuleOut(ctx, m.stem())
ret := pathForModuleOut(ctx, "checkseapp", m.stem())
// Step 1. Generate a M4 processed neverallow file
flags := m.getBuildFlags(ctx)
m4NeverallowFile := pathForModuleOut(ctx, "neverallow.m4out")
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().Text("(grep").
rule.Command().
Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
Flag("--fatal-warnings").
FlagForEachArg("-D", ctx.DeviceConfig().SepolicyM4Defs()).
Flags(flagsToM4Macros(flags)).
Inputs(android.PathsForModuleSrc(ctx, m.seappProperties.Neverallow_files)).
FlagWithOutput("> ", m4NeverallowFile)
rule.Temporary(m4NeverallowFile)
rule.Command().
Text("( grep").
Flag("-ihe").
Text("'^neverallow'").
Inputs(android.PathsForModuleSrc(ctx, m.seappProperties.Neverallow_files)).
Text(os.DevNull). // to make grep happy even when Neverallow_files is empty
Input(m4NeverallowFile).
Text(">").
Output(neverallowFile).
Text("|| true)") // to make ninja happy even when result is empty
Text("|| true )") // to make ninja happy even when result is empty
// Step 2. Generate a M4 processed contexts file
builtCtx := m.buildGeneralContexts(ctx, inputs)
// Step 3. checkseapp
rule.Temporary(neverallowFile)
checkCmd := rule.Command().BuiltTool("checkseapp").
FlagWithInput("-p ", android.PathForModuleSrc(ctx, proptools.String(m.seappProperties.Sepolicy))).
FlagWithOutput("-o ", ret).
Inputs(inputs).
Input(builtCtx).
Input(neverallowFile)
if m.shouldCheckCoredomain(ctx) {

View file

@ -29,6 +29,9 @@ func init() {
}
type neverallowTestProperties struct {
// Default modules for conf
Defaults []string
// Policy files to be tested.
Srcs []string `android:"path"`
}
@ -79,6 +82,10 @@ func (n *neverallowTestModule) loadHook(ctx android.LoadHookContext) {
Srcs: n.properties.Srcs,
Build_variant: proptools.StringPtr("user"),
Installable: proptools.BoolPtr(false),
}, &struct {
Defaults []string
}{
Defaults: n.properties.Defaults,
})
sepolicyAnalyzeConf := n.sepolicyAnalyzeConfModuleName()
@ -89,6 +96,10 @@ func (n *neverallowTestModule) loadHook(ctx android.LoadHookContext) {
Build_variant: proptools.StringPtr("user"),
Exclude_build_test: proptools.BoolPtr(true),
Installable: proptools.BoolPtr(false),
}, &struct {
Defaults []string
}{
Defaults: n.properties.Defaults,
})
}

View file

@ -429,6 +429,7 @@ se_compat_cil {
se_compat_test {
name: "sepolicy_compat_test",
defaults: ["se_policy_conf_flags_defaults"],
}
se_build_files {

View file

@ -70,6 +70,7 @@ se_build_files {
file_contexts {
name: "plat_file_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":file_contexts_files{.plat_private}"],
product_variables: {
address_sanitize: {
@ -83,6 +84,7 @@ file_contexts {
file_contexts {
name: "plat_file_contexts.recovery",
defaults: ["contexts_flags_defaults"],
srcs: [":file_contexts_files{.plat_private}"],
stem: "plat_file_contexts",
product_variables: {
@ -98,6 +100,7 @@ file_contexts {
file_contexts {
name: "vendor_file_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":file_contexts_files{.plat_vendor}",
":file_contexts_files{.vendor}",
@ -108,6 +111,7 @@ file_contexts {
file_contexts {
name: "vendor_file_contexts.recovery",
defaults: ["contexts_flags_defaults"],
srcs: [
":file_contexts_files{.plat_vendor}",
":file_contexts_files{.vendor}",
@ -119,12 +123,14 @@ file_contexts {
file_contexts {
name: "system_ext_file_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":file_contexts_files{.system_ext_private}"],
system_ext_specific: true,
}
file_contexts {
name: "system_ext_file_contexts.recovery",
defaults: ["contexts_flags_defaults"],
srcs: [":file_contexts_files{.system_ext_private}"],
stem: "system_ext_file_contexts",
recovery: true,
@ -132,12 +138,14 @@ file_contexts {
file_contexts {
name: "product_file_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":file_contexts_files{.product_private}"],
product_specific: true,
}
file_contexts {
name: "product_file_contexts.recovery",
defaults: ["contexts_flags_defaults"],
srcs: [":file_contexts_files{.product_private}"],
stem: "product_file_contexts",
recovery: true,
@ -145,6 +153,7 @@ file_contexts {
file_contexts {
name: "odm_file_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":file_contexts_files{.odm}"],
device_specific: true,
fc_sort: true,
@ -152,6 +161,7 @@ file_contexts {
file_contexts {
name: "odm_file_contexts.recovery",
defaults: ["contexts_flags_defaults"],
srcs: [":file_contexts_files{.odm}"],
stem: "odm_file_contexts",
recovery: true,
@ -160,23 +170,27 @@ file_contexts {
hwservice_contexts {
name: "plat_hwservice_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":hwservice_contexts_files{.plat_private}"],
}
hwservice_contexts {
name: "system_ext_hwservice_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":hwservice_contexts_files{.system_ext_private}"],
system_ext_specific: true,
}
hwservice_contexts {
name: "product_hwservice_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":hwservice_contexts_files{.product_private}"],
product_specific: true,
}
hwservice_contexts {
name: "vendor_hwservice_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":hwservice_contexts_files{.plat_vendor}",
":hwservice_contexts_files{.vendor}",
@ -187,17 +201,20 @@ hwservice_contexts {
hwservice_contexts {
name: "odm_hwservice_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":hwservice_contexts_files{.odm}"],
device_specific: true,
}
property_contexts {
name: "plat_property_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":property_contexts_files{.plat_private}"],
}
property_contexts {
name: "plat_property_contexts.recovery",
defaults: ["contexts_flags_defaults"],
srcs: [":property_contexts_files{.plat_private}"],
stem: "plat_property_contexts",
recovery: true,
@ -205,6 +222,7 @@ property_contexts {
property_contexts {
name: "system_ext_property_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":property_contexts_files{.system_ext_private}"],
system_ext_specific: true,
recovery_available: true,
@ -212,6 +230,7 @@ property_contexts {
property_contexts {
name: "product_property_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":property_contexts_files{.product_private}"],
product_specific: true,
recovery_available: true,
@ -219,6 +238,7 @@ property_contexts {
property_contexts {
name: "vendor_property_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":property_contexts_files{.plat_vendor}",
":property_contexts_files{.vendor}",
@ -230,6 +250,7 @@ property_contexts {
property_contexts {
name: "odm_property_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":property_contexts_files{.odm}"],
device_specific: true,
recovery_available: true,
@ -237,11 +258,13 @@ property_contexts {
service_contexts {
name: "plat_service_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":service_contexts_files{.plat_private}"],
}
service_contexts {
name: "plat_service_contexts.recovery",
defaults: ["contexts_flags_defaults"],
srcs: [":service_contexts_files{.plat_private}"],
stem: "plat_service_contexts",
recovery: true,
@ -249,6 +272,7 @@ service_contexts {
service_contexts {
name: "system_ext_service_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":service_contexts_files{.system_ext_private}"],
system_ext_specific: true,
recovery_available: true,
@ -256,6 +280,7 @@ service_contexts {
service_contexts {
name: "product_service_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":service_contexts_files{.product_private}"],
product_specific: true,
recovery_available: true,
@ -263,6 +288,7 @@ service_contexts {
service_contexts {
name: "vendor_service_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":service_contexts_files{.plat_vendor}",
":service_contexts_files{.vendor}",
@ -274,6 +300,7 @@ service_contexts {
service_contexts {
name: "odm_service_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":service_contexts_files{.odm}",
],
@ -283,23 +310,27 @@ service_contexts {
keystore2_key_contexts {
name: "plat_keystore2_key_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":keystore2_key_contexts_files{.plat_private}"],
}
keystore2_key_contexts {
name: "system_keystore2_key_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":keystore2_key_contexts_files{.system_ext_private}"],
system_ext_specific: true,
}
keystore2_key_contexts {
name: "product_keystore2_key_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":keystore2_key_contexts_files{.product_private}"],
product_specific: true,
}
keystore2_key_contexts {
name: "vendor_keystore2_key_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":keystore2_key_contexts_files{.plat_vendor}",
":keystore2_key_contexts_files{.vendor}",
@ -310,12 +341,14 @@ keystore2_key_contexts {
seapp_contexts {
name: "plat_seapp_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":seapp_contexts_files{.plat_private}"],
sepolicy: ":precompiled_sepolicy",
}
seapp_contexts {
name: "system_ext_seapp_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":seapp_contexts_files{.system_ext_private}"],
neverallow_files: [":seapp_contexts_files{.plat_private}"],
system_ext_specific: true,
@ -324,6 +357,7 @@ seapp_contexts {
seapp_contexts {
name: "product_seapp_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [":seapp_contexts_files{.product_private}"],
neverallow_files: [
":seapp_contexts_files{.plat_private}",
@ -335,6 +369,7 @@ seapp_contexts {
seapp_contexts {
name: "vendor_seapp_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":seapp_contexts_files{.plat_vendor}",
":seapp_contexts_files{.vendor}",
@ -351,6 +386,7 @@ seapp_contexts {
seapp_contexts {
name: "odm_seapp_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":seapp_contexts_files{.odm}",
],
@ -365,6 +401,7 @@ seapp_contexts {
vndservice_contexts {
name: "vndservice_contexts",
defaults: ["contexts_flags_defaults"],
srcs: [
":vndservice_contexts_files{.plat_vendor}",
":vndservice_contexts_files{.vendor}",

32
flagging/Android.bp Normal file
View file

@ -0,0 +1,32 @@
// Copyright (C) 2023 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file contains a list of flags for sepolicy.
se_policy_conf_defaults {
name: "se_policy_conf_flags_defaults",
srcs: [":sepolicy_flagging_macros"],
flags: [],
}
contexts_defaults {
name: "contexts_flags_defaults",
srcs: [":sepolicy_flagging_macros"],
neverallow_files: [":sepolicy_flagging_macros"], // for seapp_contexts
flags: [],
}
filegroup {
name: "sepolicy_flagging_macros",
srcs: ["te_macros"],
}

9
flagging/te_macros Normal file
View file

@ -0,0 +1,9 @@
####################################
# is_flag_enabled(flag, rules)
# SELinux rules which apply only if given feature is turned on
define(`is_flag_enabled', `ifelse(target_flag_$1, `true', $2, )')
####################################
# is_flag_disabled(flag, rules)
# SELinux rules which apply only if given feature is turned off
define(`is_flag_disabled', `ifelse(target_flag_$1, `true', , $2)')

View file

@ -76,7 +76,7 @@ if len(violations) > 0:
print('%d violations found:' % len(violations))
print('\n'.join(violations))
print('******************************')
print('%s contains properties which are not properly namespaced.' % args.property_contexts)
print("vendor's and odm's property_contexts MUST use ONLY vendor-prefixed properties.")
print('This is enforced by VTS, so please fix such offending properties.')
if args.allowed_property_prefix:
print('Allowed property prefixes for %s: %s' % (args.property_contexts, args.allowed_property_prefix))