40073d4c7f
These variables are deprecated. Bug: 183362912 Test: Presubmit; Noop Change-Id: I80db5342044a06feb1451fbe661989fe4d191e74
199 lines
6.1 KiB
Go
199 lines
6.1 KiB
Go
// Copyright 2021 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.
|
|
|
|
package selinux
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
|
|
"android/soong/android"
|
|
)
|
|
|
|
func init() {
|
|
android.RegisterModuleType("se_build_files", buildFilesFactory)
|
|
}
|
|
|
|
// 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".
|
|
func buildFilesFactory() android.Module {
|
|
module := &buildFiles{}
|
|
module.AddProperties(&module.properties)
|
|
android.InitAndroidModule(module)
|
|
return module
|
|
}
|
|
|
|
type buildFilesProperties struct {
|
|
// list of source file suffixes used to collect selinux policy files.
|
|
// Source files will be looked up in the following local directories:
|
|
// system/sepolicy/{public, private, vendor, reqd_mask}
|
|
// and directories specified by following config variables:
|
|
// BOARD_SEPOLICY_DIRS, BOARD_ODM_SEPOLICY_DIRS
|
|
// SYSTEM_EXT_PUBLIC_SEPOLICY_DIR, SYSTEM_EXT_PRIVATE_SEPOLICY_DIR
|
|
Srcs []string
|
|
}
|
|
|
|
type buildFiles struct {
|
|
android.ModuleBase
|
|
properties buildFilesProperties
|
|
|
|
srcs map[string]android.Paths
|
|
}
|
|
|
|
func (b *buildFiles) findSrcsInDirs(ctx android.ModuleContext, dirs ...string) android.Paths {
|
|
result := android.Paths{}
|
|
for _, file := range b.properties.Srcs {
|
|
for _, dir := range dirs {
|
|
path := filepath.Join(dir, file)
|
|
files, err := ctx.GlobWithDeps(path, nil)
|
|
if err != nil {
|
|
ctx.ModuleErrorf("glob: %s", err.Error())
|
|
}
|
|
for _, f := range files {
|
|
result = append(result, android.PathForSource(ctx, f))
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (b *buildFiles) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
// do nothing
|
|
}
|
|
|
|
func (b *buildFiles) OutputFiles(tag string) (android.Paths, error) {
|
|
if paths, ok := b.srcs[tag]; ok {
|
|
return paths, nil
|
|
}
|
|
|
|
return nil, fmt.Errorf("unknown tag %q. Supported tags are: %q", tag, strings.Join(android.SortedStringKeys(b.srcs), " "))
|
|
}
|
|
|
|
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))
|
|
}
|
|
}
|
|
|
|
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)...)
|
|
}
|