Refactor Android.bp build modules for readability
When we compile sepolicy files into a cil file, we first gather all sepolicy files to create a conf file, and then convert the conf file to a cil file with checkpolicy. The problem is that checkpolicy is sensitive to the input order; the conf file should contain statements in a specific order: classes, initial_sid, access vectors, macros, mls, etc. This restriction has made Android.bp migration difficult, and we had to create a magical module called "se_build_files" to correctly include source files in the designated order. It works, but significant readability problem has happened. For example, when we write ":se_build_files{.system_ext_public}", how can we easily figure out that the tag actually includes plat public + system_ext public + reqd mask, without taking a look at the build system code? This change refactors the se_build_files module and se_policy_conf module, so we can easily see the desginated files for each module, just like we did in the Android.mk. se_policy_conf module now stably sorts source files in an order which will make checkpolicy happy. se_build_files module is also refactored, so one tag can represent exactly one set of policy files, rather than doing magical works behind the scene. For example, system_ext public policy module is changed from: se_policy_conf { name: "system_ext_pub_policy.conf", // se_build_files automatically adds plat public and reqd mask srcs: [":se_build_files{.system_ext_public}"], } to: se_policy_conf { name: "system_ext_pub_policy.conf", // se_policy_conf automatically sorts the input files srcs: [ ":se_build_files{.plat_public}", ":se_build_files{.system_ext_public}", ":se_build_files{.reqd_mask}", ], } Bug: 209933272 Test: build and diff before/after Change-Id: I97a76ed910645c1607d913fd646c27e87af0afd3
This commit is contained in:
parent
04a2389d59
commit
0a707fadb2
3 changed files with 110 additions and 124 deletions
70
Android.bp
70
Android.bp
|
@ -661,6 +661,14 @@ se_build_files {
|
|||
],
|
||||
}
|
||||
|
||||
reqd_mask_policy = [":se_build_files{.reqd_mask}"]
|
||||
plat_public_policy = [":se_build_files{.plat_public}"]
|
||||
plat_private_policy = [":se_build_files{.plat_private}"]
|
||||
system_ext_public_policy = [":se_build_files{.system_ext_public}"]
|
||||
system_ext_private_policy = [":se_build_files{.system_ext_private}"]
|
||||
product_public_policy = [":se_build_files{.product_public}"]
|
||||
product_private_policy = [":se_build_files{.product_private}"]
|
||||
|
||||
// reqd_policy_mask - a policy.conf file which contains only the bare minimum
|
||||
// policy necessary to use checkpolicy.
|
||||
//
|
||||
|
@ -671,7 +679,7 @@ se_build_files {
|
|||
// policy and subsequent removal of CIL policy that should not be exported.
|
||||
se_policy_conf {
|
||||
name: "reqd_policy_mask.conf",
|
||||
srcs: [":se_build_files{.reqd_mask}"],
|
||||
srcs: reqd_mask_policy,
|
||||
installable: false,
|
||||
}
|
||||
|
||||
|
@ -706,7 +714,10 @@ se_policy_cil {
|
|||
//
|
||||
se_policy_conf {
|
||||
name: "pub_policy.conf",
|
||||
srcs: [":se_build_files{.product_public}"], // product_ includes system and system_ext
|
||||
srcs: plat_public_policy +
|
||||
system_ext_public_policy +
|
||||
product_public_policy +
|
||||
reqd_mask_policy,
|
||||
installable: false,
|
||||
}
|
||||
|
||||
|
@ -720,7 +731,9 @@ se_policy_cil {
|
|||
|
||||
se_policy_conf {
|
||||
name: "system_ext_pub_policy.conf",
|
||||
srcs: [":se_build_files{.system_ext_public}"], // system_ext_public includes system
|
||||
srcs: plat_public_policy +
|
||||
system_ext_public_policy +
|
||||
reqd_mask_policy,
|
||||
installable: false,
|
||||
}
|
||||
|
||||
|
@ -734,7 +747,8 @@ se_policy_cil {
|
|||
|
||||
se_policy_conf {
|
||||
name: "plat_pub_policy.conf",
|
||||
srcs: [":se_build_files{.plat_public}"],
|
||||
srcs: plat_public_policy +
|
||||
reqd_mask_policy,
|
||||
installable: false,
|
||||
}
|
||||
|
||||
|
@ -753,7 +767,8 @@ se_policy_cil {
|
|||
// currently being attributized.
|
||||
se_policy_conf {
|
||||
name: "plat_sepolicy.conf",
|
||||
srcs: [":se_build_files{.plat}"],
|
||||
srcs: plat_public_policy +
|
||||
plat_private_policy,
|
||||
installable: false,
|
||||
}
|
||||
|
||||
|
@ -766,7 +781,8 @@ se_policy_cil {
|
|||
// userdebug_plat_policy.conf - the userdebug version plat_sepolicy.cil
|
||||
se_policy_conf {
|
||||
name: "userdebug_plat_sepolicy.conf",
|
||||
srcs: [":se_build_files{.plat}"],
|
||||
srcs: plat_public_policy +
|
||||
plat_private_policy,
|
||||
build_variant: "userdebug",
|
||||
installable: false,
|
||||
}
|
||||
|
@ -815,7 +831,10 @@ 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",
|
||||
srcs: [":se_build_files{.system_ext}"],
|
||||
srcs: plat_public_policy +
|
||||
plat_private_policy +
|
||||
system_ext_public_policy +
|
||||
system_ext_private_policy,
|
||||
installable: false,
|
||||
}
|
||||
|
||||
|
@ -831,7 +850,12 @@ se_policy_cil {
|
|||
// which will ship with the device. Product policy is not attributized
|
||||
se_policy_conf {
|
||||
name: "product_sepolicy.conf",
|
||||
srcs: [":se_build_files{.product}"],
|
||||
srcs: plat_public_policy +
|
||||
plat_private_policy +
|
||||
system_ext_public_policy +
|
||||
system_ext_private_policy +
|
||||
product_public_policy +
|
||||
product_private_policy,
|
||||
installable: false,
|
||||
}
|
||||
|
||||
|
@ -1017,7 +1041,8 @@ prebuilt_etc {
|
|||
//////////////////////////////////
|
||||
se_policy_conf {
|
||||
name: "general_sepolicy.conf",
|
||||
srcs: [":se_build_files{.plat}"],
|
||||
srcs: plat_public_policy +
|
||||
plat_private_policy,
|
||||
build_variant: "user",
|
||||
cts: true,
|
||||
exclude_build_test: true,
|
||||
|
@ -1032,7 +1057,8 @@ se_policy_conf {
|
|||
//////////////////////////////////
|
||||
se_policy_conf {
|
||||
name: "base_plat_sepolicy.conf",
|
||||
srcs: [":se_build_files{.plat}"],
|
||||
srcs: plat_public_policy +
|
||||
plat_private_policy,
|
||||
build_variant: "user",
|
||||
installable: false,
|
||||
}
|
||||
|
@ -1053,7 +1079,10 @@ se_policy_binary {
|
|||
|
||||
se_policy_conf {
|
||||
name: "base_system_ext_sepolicy.conf",
|
||||
srcs: [":se_build_files{.system_ext}"],
|
||||
srcs: plat_public_policy +
|
||||
plat_private_policy +
|
||||
system_ext_public_policy +
|
||||
system_ext_private_policy,
|
||||
build_variant: "user",
|
||||
installable: false,
|
||||
}
|
||||
|
@ -1076,7 +1105,12 @@ se_policy_binary {
|
|||
|
||||
se_policy_conf {
|
||||
name: "base_product_sepolicy.conf",
|
||||
srcs: [":se_build_files{.product}"],
|
||||
srcs: plat_public_policy +
|
||||
plat_private_policy +
|
||||
system_ext_public_policy +
|
||||
system_ext_private_policy +
|
||||
product_public_policy +
|
||||
product_private_policy,
|
||||
build_variant: "user",
|
||||
installable: false,
|
||||
}
|
||||
|
@ -1099,7 +1133,8 @@ se_policy_binary {
|
|||
|
||||
se_policy_conf {
|
||||
name: "base_plat_pub_policy.conf",
|
||||
srcs: [":se_build_files{.plat_public}"],
|
||||
srcs: plat_public_policy +
|
||||
reqd_mask_policy,
|
||||
build_variant: "user",
|
||||
installable: false,
|
||||
}
|
||||
|
@ -1114,7 +1149,9 @@ se_policy_cil {
|
|||
|
||||
se_policy_conf {
|
||||
name: "base_system_ext_pub_policy.conf",
|
||||
srcs: [":se_build_files{.system_ext_public}"], // system_ext_public includes system
|
||||
srcs: plat_public_policy +
|
||||
system_ext_public_policy +
|
||||
reqd_mask_policy,
|
||||
build_variant: "user",
|
||||
installable: false,
|
||||
}
|
||||
|
@ -1129,7 +1166,10 @@ se_policy_cil {
|
|||
|
||||
se_policy_conf {
|
||||
name: "base_product_pub_policy.conf",
|
||||
srcs: [":se_build_files{.product_public}"], // product_ includes system and system_ext
|
||||
srcs: plat_public_policy +
|
||||
system_ext_public_policy +
|
||||
product_public_policy +
|
||||
reqd_mask_policy,
|
||||
build_variant: "user",
|
||||
installable: false,
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ package selinux
|
|||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"android/soong/android"
|
||||
|
@ -29,8 +28,8 @@ func init() {
|
|||
|
||||
// se_build_files gathers policy files from sepolicy dirs, and acts like a filegroup. A tag with
|
||||
// partition(plat, system_ext, product) and scope(public, private) is used to select directories.
|
||||
// Supported tags are: "plat", "plat_public", "system_ext", "system_ext_public", "product",
|
||||
// "product_public", and "reqd_mask".
|
||||
// Supported tags are: "plat_public", "plat_private", "system_ext_public", "system_ext_private",
|
||||
// "product_public", "product_private", and "reqd_mask".
|
||||
func buildFilesFactory() android.Module {
|
||||
module := &buildFiles{}
|
||||
module.AddProperties(&module.properties)
|
||||
|
@ -86,114 +85,18 @@ func (b *buildFiles) OutputFiles(tag string) (android.Paths, error) {
|
|||
|
||||
var _ android.OutputFileProducer = (*buildFiles)(nil)
|
||||
|
||||
type partition int
|
||||
|
||||
const (
|
||||
system partition = iota
|
||||
system_ext
|
||||
product
|
||||
)
|
||||
|
||||
type scope int
|
||||
|
||||
const (
|
||||
public scope = iota
|
||||
private
|
||||
)
|
||||
|
||||
type sepolicyDir struct {
|
||||
partition partition
|
||||
scope scope
|
||||
paths []string
|
||||
}
|
||||
|
||||
func (p partition) String() string {
|
||||
switch p {
|
||||
case system:
|
||||
return "plat"
|
||||
case system_ext:
|
||||
return "system_ext"
|
||||
case product:
|
||||
return "product"
|
||||
default:
|
||||
panic(fmt.Sprintf("Unknown partition %#v", p))
|
||||
}
|
||||
tag string
|
||||
paths []string
|
||||
}
|
||||
|
||||
func (b *buildFiles) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
// Sepolicy directories should be included in the following order.
|
||||
// - system_public
|
||||
// - system_private
|
||||
// - system_ext_public
|
||||
// - system_ext_private
|
||||
// - product_public
|
||||
// - product_private
|
||||
dirs := []sepolicyDir{
|
||||
sepolicyDir{partition: system, scope: public, paths: []string{filepath.Join(ctx.ModuleDir(), "public")}},
|
||||
sepolicyDir{partition: system, scope: private, paths: []string{filepath.Join(ctx.ModuleDir(), "private")}},
|
||||
sepolicyDir{partition: system_ext, scope: public, paths: ctx.DeviceConfig().SystemExtPublicSepolicyDirs()},
|
||||
sepolicyDir{partition: system_ext, scope: private, paths: ctx.DeviceConfig().SystemExtPrivateSepolicyDirs()},
|
||||
sepolicyDir{partition: product, scope: public, paths: ctx.Config().ProductPublicSepolicyDirs()},
|
||||
sepolicyDir{partition: product, scope: private, paths: ctx.Config().ProductPrivateSepolicyDirs()},
|
||||
}
|
||||
|
||||
if !sort.SliceIsSorted(dirs, func(i, j int) bool {
|
||||
if dirs[i].partition != dirs[j].partition {
|
||||
return dirs[i].partition < dirs[j].partition
|
||||
}
|
||||
|
||||
return dirs[i].scope < dirs[j].scope
|
||||
}) {
|
||||
panic("dirs is not sorted")
|
||||
}
|
||||
|
||||
// Exported cil policy files are built with the following policies.
|
||||
//
|
||||
// - plat_pub_policy.cil: exported 'system'
|
||||
// - system_ext_pub_policy.cil: exported 'system' and 'system_ext'
|
||||
// - pub_policy.cil: exported 'system', 'system_ext', and 'product'
|
||||
//
|
||||
// cil policy files are built with the following policies.
|
||||
//
|
||||
// - plat_policy.cil: 'system', including private
|
||||
// - system_ext_policy.cil: 'system_ext', including private
|
||||
// - product_sepolicy.cil: 'product', including private
|
||||
//
|
||||
// gatherDirsFor collects all needed directories for given partition and scope. For example,
|
||||
//
|
||||
// - gatherDirsFor(system_ext, private) will return system + system_ext (including private)
|
||||
// - gatherDirsFor(product, public) will return system + system_ext + product (public only)
|
||||
//
|
||||
// "dirs" should be sorted before calling this.
|
||||
gatherDirsFor := func(p partition, s scope) []string {
|
||||
var ret []string
|
||||
|
||||
for _, d := range dirs {
|
||||
if d.partition <= p && d.scope <= s {
|
||||
ret = append(ret, d.paths...)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
reqdMaskDir := filepath.Join(ctx.ModuleDir(), "reqd_mask")
|
||||
|
||||
b.srcs = make(map[string]android.Paths)
|
||||
b.srcs[".reqd_mask"] = b.findSrcsInDirs(ctx, reqdMaskDir)
|
||||
|
||||
for _, p := range []partition{system, system_ext, product} {
|
||||
b.srcs["."+p.String()] = b.findSrcsInDirs(ctx, gatherDirsFor(p, private)...)
|
||||
|
||||
// reqd_mask is needed for public policies
|
||||
b.srcs["."+p.String()+"_public"] = b.findSrcsInDirs(ctx, append(gatherDirsFor(p, public), reqdMaskDir)...)
|
||||
}
|
||||
|
||||
// A special tag, "plat_vendor", includes minimized vendor policies required to boot.
|
||||
// - system/sepolicy/public
|
||||
// - system/sepolicy/reqd_mask
|
||||
// - system/sepolicy/vendor
|
||||
// This is for minimized vendor partition, e.g. microdroid's vendor
|
||||
platVendorDir := filepath.Join(ctx.ModuleDir(), "vendor")
|
||||
b.srcs[".plat_vendor"] = b.findSrcsInDirs(ctx, append(gatherDirsFor(system, public), reqdMaskDir, platVendorDir)...)
|
||||
b.srcs[".reqd_mask"] = b.findSrcsInDirs(ctx, filepath.Join(ctx.ModuleDir(), "reqd_mask"))
|
||||
b.srcs[".plat_public"] = b.findSrcsInDirs(ctx, filepath.Join(ctx.ModuleDir(), "public"))
|
||||
b.srcs[".plat_private"] = b.findSrcsInDirs(ctx, filepath.Join(ctx.ModuleDir(), "private"))
|
||||
b.srcs[".system_ext_public"] = b.findSrcsInDirs(ctx, ctx.DeviceConfig().SystemExtPublicSepolicyDirs()...)
|
||||
b.srcs[".system_ext_private"] = b.findSrcsInDirs(ctx, ctx.DeviceConfig().SystemExtPrivateSepolicyDirs()...)
|
||||
b.srcs[".product_public"] = b.findSrcsInDirs(ctx, ctx.Config().ProductPublicSepolicyDirs()...)
|
||||
b.srcs[".product_private"] = b.findSrcsInDirs(ctx, ctx.Config().ProductPrivateSepolicyDirs()...)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,9 @@ package selinux
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint/proptools"
|
||||
|
||||
|
@ -31,6 +33,31 @@ const (
|
|||
PolicyVers = 30
|
||||
)
|
||||
|
||||
// This order should be kept. checkpolicy syntax requires it.
|
||||
var policyConfOrder = []string{
|
||||
"security_classes",
|
||||
"initial_sids",
|
||||
"access_vectors",
|
||||
"global_macros",
|
||||
"neverallow_macros",
|
||||
"mls_macros",
|
||||
"mls_decl",
|
||||
"mls",
|
||||
"policy_capabilities",
|
||||
"te_macros",
|
||||
"attributes",
|
||||
"ioctl_defines",
|
||||
"ioctl_macros",
|
||||
"*.te",
|
||||
"roles_decl",
|
||||
"roles",
|
||||
"users",
|
||||
"initial_sid_contexts",
|
||||
"fs_use",
|
||||
"genfs_contexts",
|
||||
"port_contexts",
|
||||
}
|
||||
|
||||
func init() {
|
||||
android.RegisterModuleType("se_policy_conf", policyConfFactory)
|
||||
android.RegisterModuleType("se_policy_cil", policyCilFactory)
|
||||
|
@ -143,9 +170,25 @@ func (c *policyConf) enforceDebugfsRestrictions(ctx android.ModuleContext) strin
|
|||
return strconv.FormatBool(ctx.DeviceConfig().BuildDebugfsRestrictionsEnabled())
|
||||
}
|
||||
|
||||
func findPolicyConfOrder(name string) int {
|
||||
for idx, pattern := range policyConfOrder {
|
||||
if pattern == name || (pattern == "*.te" && strings.HasSuffix(name, ".te")) {
|
||||
return idx
|
||||
}
|
||||
}
|
||||
// name is not matched
|
||||
return len(policyConfOrder)
|
||||
}
|
||||
|
||||
func (c *policyConf) transformPolicyToConf(ctx android.ModuleContext) android.OutputPath {
|
||||
conf := android.PathForModuleOut(ctx, "conf").OutputPath
|
||||
rule := android.NewRuleBuilder(pctx, ctx)
|
||||
|
||||
srcs := android.PathsForModuleSrc(ctx, c.properties.Srcs)
|
||||
sort.SliceStable(srcs, func(x, y int) bool {
|
||||
return findPolicyConfOrder(srcs[x].Base()) < findPolicyConfOrder(srcs[y].Base())
|
||||
})
|
||||
|
||||
rule.Command().Tool(ctx.Config().PrebuiltBuildTool(ctx, "m4")).
|
||||
Flag("--fatal-warnings").
|
||||
FlagForEachArg("-D ", ctx.DeviceConfig().SepolicyM4Defs()).
|
||||
|
@ -164,7 +207,7 @@ func (c *policyConf) transformPolicyToConf(ctx android.ModuleContext) android.Ou
|
|||
FlagWithArg("-D target_requires_insecure_execmem_for_swiftshader=", strconv.FormatBool(ctx.DeviceConfig().RequiresInsecureExecmemForSwiftshader())).
|
||||
FlagWithArg("-D target_enforce_debugfs_restriction=", c.enforceDebugfsRestrictions(ctx)).
|
||||
Flag("-s").
|
||||
Inputs(android.PathsForModuleSrc(ctx, c.properties.Srcs)).
|
||||
Inputs(srcs).
|
||||
Text("> ").Output(conf)
|
||||
|
||||
rule.Build("conf", "Transform policy to conf: "+ctx.ModuleName())
|
||||
|
|
Loading…
Reference in a new issue