Merge "Keystore 2.0: Allow apps to get the Keystore state."
diff --git a/Android.bp b/Android.bp
index 8fa57ca..aca6e40 100644
--- a/Android.bp
+++ b/Android.bp
@@ -735,3 +735,30 @@
     relative_install_path: "selinux",
     installable: false,
 }
+
+se_build_files {
+    name: "se_build_files",
+    srcs: [
+        "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",
+    ],
+}
diff --git a/apex/com.android.sdkext-file_contexts b/apex/com.android.sdkext-file_contexts
index 2d59dda..551a12c 100644
--- a/apex/com.android.sdkext-file_contexts
+++ b/apex/com.android.sdkext-file_contexts
@@ -1,2 +1,3 @@
-(/.*)?                u:object_r:system_file:s0
-/bin/derive_sdk       u:object_r:derive_sdk_exec:s0
+(/.*)?                       u:object_r:system_file:s0
+/bin/derive_classpath        u:object_r:derive_classpath_exec:s0
+/bin/derive_sdk              u:object_r:derive_sdk_exec:s0
diff --git a/build/soong/Android.bp b/build/soong/Android.bp
index 5f951ce..54173e0 100644
--- a/build/soong/Android.bp
+++ b/build/soong/Android.bp
@@ -31,6 +31,7 @@
         "soong-sysprop",
     ],
     srcs: [
+        "build_files.go",
         "cil_compat_map.go",
         "filegroup.go",
         "selinux.go",
diff --git a/build/soong/build_files.go b/build/soong/build_files.go
new file mode 100644
index 0000000..1704366
--- /dev/null
+++ b/build/soong/build_files.go
@@ -0,0 +1,191 @@
+// 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
+	// BOARD_PLAT_PUBLIC_SEPOLICY_DIR, BOARD_PLAT_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)...)
+	}
+}
diff --git a/private/apexd.te b/private/apexd.te
index d65de19..44e38b6 100644
--- a/private/apexd.te
+++ b/private/apexd.te
@@ -13,6 +13,10 @@
 allow apexd apex_metadata_file:dir create_dir_perms;
 allow apexd apex_metadata_file:file create_file_perms;
 
+# Allow reserving space on /data/apex/ota_reserved for apex decompression
+allow apexd apex_ota_reserved_file:dir create_dir_perms;
+allow apexd apex_ota_reserved_file:file create_file_perms;
+
 # Allow apexd to create files and directories for snapshots of apex data
 allow apexd apex_art_data_file:dir { create_dir_perms relabelto };
 allow apexd apex_art_data_file:file { create_file_perms relabelto };
diff --git a/private/derive_classpath.te b/private/derive_classpath.te
new file mode 100644
index 0000000..15f1973
--- /dev/null
+++ b/private/derive_classpath.te
@@ -0,0 +1,9 @@
+
+# Domain for derive_classpath
+type derive_classpath, domain, coredomain;
+type derive_classpath_exec, system_file_type, exec_type, file_type;
+init_daemon_domain(derive_classpath)
+
+# Create /data/system/environ/classpath file
+allow derive_classpath environ_system_data_file:dir rw_dir_perms;
+allow derive_classpath environ_system_data_file:file create_file_perms;
diff --git a/private/file.te b/private/file.te
index 4b0f48a..984a7b6 100644
--- a/private/file.te
+++ b/private/file.te
@@ -33,6 +33,9 @@
 # /data/gsi/ota
 type ota_image_data_file, file_type, data_file_type, core_data_file_type;
 
+# /data/gsi_persistent_data
+type gsi_persistent_data_file, file_type, data_file_type, core_data_file_type;
+
 # /data/misc/emergencynumberdb
 type emergency_data_file, file_type, data_file_type, core_data_file_type;
 
@@ -50,3 +53,6 @@
 
 # /data/misc/odsign
 type odsign_data_file, file_type, data_file_type, core_data_file_type;
+
+# /data/system/environ
+type environ_system_data_file, file_type, data_file_type, core_data_file_type;
diff --git a/private/file_contexts b/private/file_contexts
index a4a0449..1347797 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -504,6 +504,7 @@
 #
 /data		u:object_r:system_data_root_file:s0
 /data/(.*)?		u:object_r:system_data_file:s0
+/data/system/environ(/.*)? u:object_r:environ_system_data_file:s0
 /data/system/packages\.list u:object_r:packages_list_file:s0
 /data/unencrypted(/.*)?         u:object_r:unencrypted_data_file:s0
 /data/backup(/.*)?		u:object_r:backup_data_file:s0
@@ -532,6 +533,7 @@
 /data/app-private(/.*)?               u:object_r:apk_private_data_file:s0
 /data/app-private/vmdl.*\.tmp(/.*)?   u:object_r:apk_private_tmp_file:s0
 /data/gsi(/.*)?        u:object_r:gsi_data_file:s0
+/data/gsi_persistent_data    u:object_r:gsi_persistent_data_file:s0
 /data/gsi/ota(/.*)?    u:object_r:ota_image_data_file:s0
 /data/tombstones(/.*)?	u:object_r:tombstone_data_file:s0
 /data/vendor/tombstones/wifi(/.*)? u:object_r:tombstone_wifi_data_file:s0
diff --git a/private/network_stack.te b/private/network_stack.te
index 9598fa5..6fa3055 100644
--- a/private/network_stack.te
+++ b/private/network_stack.te
@@ -49,10 +49,9 @@
 allow network_stack bpfloader:bpf { map_read map_write prog_run };
 
 # Only the bpfloader and the network_stack should ever touch 'fs_bpf_tethering' programs/maps.
-# TODO: remove netd once netd/tethering mainline module split is complete
 # Unfortunately init/vendor_init have all sorts of extra privs
-neverallow { domain -bpfloader -init -netd -network_stack -vendor_init } fs_bpf_tethering:dir ~getattr;
-neverallow { domain -bpfloader -init -netd -network_stack -vendor_init } fs_bpf_tethering:file *;
+neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_tethering:dir ~getattr;
+neverallow { domain -bpfloader -init -network_stack -vendor_init } fs_bpf_tethering:file *;
 
-neverallow { domain -bpfloader -netd -network_stack } fs_bpf_tethering:dir ~{ getattr open read search setattr };
-neverallow { domain -bpfloader -netd -network_stack } fs_bpf_tethering:file ~{ map open read setattr };
+neverallow { domain -bpfloader -network_stack } fs_bpf_tethering:dir ~{ getattr open read search setattr };
+neverallow { domain -bpfloader -network_stack } fs_bpf_tethering:file ~{ map open read setattr };
diff --git a/private/system_server.te b/private/system_server.te
index 34b3d9f..0994f98 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -1265,6 +1265,9 @@
 allow system_server watchdog_metadata_file:dir rw_dir_perms;
 allow system_server watchdog_metadata_file:file create_file_perms;
 
+allow system_server gsi_persistent_data_file:dir rw_dir_perms;
+allow system_server gsi_persistent_data_file:file create_file_perms;
+
 # Allow system server r access to /system/bin/surfaceflinger for PinnerService.
 allow system_server surfaceflinger_exec:file r_file_perms;
 
diff --git a/public/netd.te b/public/netd.te
index 4472938..ff0bff6 100644
--- a/public/netd.te
+++ b/public/netd.te
@@ -64,9 +64,8 @@
 
 r_dir_file(netd, cgroup_v2)
 
-# TODO: remove 'fs_bpf_tethering' once netd/tethering mainline module split is completed.
-allow netd { fs_bpf fs_bpf_tethering }:dir search;
-allow netd { fs_bpf fs_bpf_tethering }:file { read write };
+allow netd fs_bpf:dir search;
+allow netd fs_bpf:file { read write };
 
 # TODO: netd previously thought it needed these permissions to do WiFi related
 #       work.  However, after all the WiFi stuff is gone, we still need them.
diff --git a/public/update_engine.te b/public/update_engine.te
index 206d29c..b7cf827 100644
--- a/public/update_engine.te
+++ b/public/update_engine.te
@@ -29,14 +29,6 @@
 allow update_engine update_engine_log_data_file:dir create_dir_perms;
 allow update_engine update_engine_log_data_file:file create_file_perms;
 
-# TODO(b/172911822): remove these access when we have transferred
-# reservation responsibility to apexd
-
-# Allow reserving space on /data/apex/ota_reserved for apex decompression
-allow update_engine apex_ota_reserved_file:dir create_dir_perms;
-allow update_engine apex_ota_reserved_file:file create_file_perms;
-allow update_engine apex_data_file:dir search;
-
 # Don't allow kernel module loading, just silence the logs.
 dontaudit update_engine kernel:system module_request;