Merge "Add charger_vendor type"
diff --git a/Android.bp b/Android.bp
index 9a13c9c..d22010c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -661,6 +661,14 @@
     ],
 }
 
+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 @@
 // 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_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_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_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 @@
 // 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 @@
 // 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 @@
 // 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 @@
 // 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 @@
 //////////////////////////////////
 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 {
     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_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_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_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_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_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,
 }
diff --git a/build/Android.bp b/build/Android.bp
index 5298f71..a7d56f8 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -31,12 +31,4 @@
     "secilc",
     "version_policy",
   ],
-  version: {
-    py2: {
-      enabled: true,
-    },
-    py3: {
-      enabled: false,
-    },
-  },
 }
diff --git a/build/build_sepolicy.py b/build/build_sepolicy.py
old mode 100644
new mode 100755
index 285bfea..ce0548a
--- a/build/build_sepolicy.py
+++ b/build/build_sepolicy.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python3
+#
 # Copyright 2018 - The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/build/file_utils.py b/build/file_utils.py
index 9f95f52..e3210ed 100644
--- a/build/file_utils.py
+++ b/build/file_utils.py
@@ -39,7 +39,7 @@
         patterns.extend(open(f).readlines())
 
     # Copy lines that are not in the pattern.
-    tmp_output = tempfile.NamedTemporaryFile()
+    tmp_output = tempfile.NamedTemporaryFile(mode='w+')
     with open(input_file, 'r') as in_file:
         tmp_output.writelines(line for line in in_file.readlines()
                               if line not in patterns)
diff --git a/build/soong/build_files.go b/build/soong/build_files.go
index 5de6122..8f77e4f 100644
--- a/build/soong/build_files.go
+++ b/build/soong/build_files.go
@@ -17,7 +17,6 @@
 import (
 	"fmt"
 	"path/filepath"
-	"sort"
 	"strings"
 
 	"android/soong/android"
@@ -29,8 +28,8 @@
 
 // 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 @@
 
 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()...)
 }
diff --git a/build/soong/policy.go b/build/soong/policy.go
index 82fabe3..8d0e1a4 100644
--- a/build/soong/policy.go
+++ b/build/soong/policy.go
@@ -17,7 +17,9 @@
 import (
 	"fmt"
 	"os"
+	"sort"
 	"strconv"
+	"strings"
 
 	"github.com/google/blueprint/proptools"
 
@@ -31,6 +33,31 @@
 	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 @@
 	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 @@
 		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())
diff --git a/microdroid/TEST_MAPPING b/microdroid/TEST_MAPPING
new file mode 100644
index 0000000..f6e1c4f
--- /dev/null
+++ b/microdroid/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "imports": [
+    {
+      "path": "packages/modules/Virtualization"
+    }
+  ]
+}
diff --git a/microdroid/system/private/apkdmverity.te b/microdroid/system/private/apkdmverity.te
index c3f718b..84e1575 100644
--- a/microdroid/system/private/apkdmverity.te
+++ b/microdroid/system/private/apkdmverity.te
@@ -36,7 +36,6 @@
 allow apkdmverity kmsg_device:chr_file w_file_perms;
 
 # apkdmverity is forked from microdroid_manager
-# TODO(inseob): remove this
 allow apkdmverity microdroid_manager:fd use;
 
 # Only microdroid_manager can run apkdmverity
diff --git a/microdroid/system/private/compos.te b/microdroid/system/private/compos.te
index b8ad335..7866b20 100644
--- a/microdroid/system/private/compos.te
+++ b/microdroid/system/private/compos.te
@@ -28,5 +28,13 @@
 # metadata. See b/196635431.
 allow compos authfs_fuse:file getattr;
 
-# Allow domain transition into dex2oat.
+# Allow creating the odrefresh output directory in authfs.
+allow compos authfs_fuse:dir create_dir_perms;
+
+# Allow locating the authfs mount directory.
+allow compos authfs_data_file:dir { search };
+
+# Allow domain transition into odrefresh and dex2oat.
+# TODO(b/209008712): Remove dex2oat once the migration is done.
+domain_auto_trans(compos, odrefresh_exec, odrefresh)
 domain_auto_trans(compos, dex2oat_exec, dex2oat)
diff --git a/microdroid/system/private/dex2oat.te b/microdroid/system/private/dex2oat.te
index bf44251..0f8b905 100644
--- a/microdroid/system/private/dex2oat.te
+++ b/microdroid/system/private/dex2oat.te
@@ -7,6 +7,7 @@
 # Allow dex2oat to use FDs from authfs_service via compos.
 allow dex2oat authfs_service:fd use;
 allow dex2oat compos:fd use;
+allow dex2oat odrefresh:fd use;
 
 # Allow dex2oat to read/write FDs on authfs_fuse filesystem.
 allow dex2oat authfs_fuse:file { read write getattr map };
diff --git a/microdroid/system/private/domain.te b/microdroid/system/private/domain.te
index c852268..2329a1d 100644
--- a/microdroid/system/private/domain.te
+++ b/microdroid/system/private/domain.te
@@ -271,6 +271,14 @@
 # Properties that microdroid doesn't have but some still want to read.
 dontaudit domain { heapprofd_prop timezone_prop }:file r_file_perms;
 
+###
+### neverallow rules
+###
+
 # Don't allow raw read/write/open access to generic devices.
 # Rather force a relabel to a more specific type.
 neverallow domain device:chr_file { open read write };
+
+# No executable memory unless backed by an unmodified file
+neverallow * self:process { execmem execheap execstack };
+neverallow * *:file execmod;
diff --git a/microdroid/system/private/file.te b/microdroid/system/private/file.te
index cbbd379..18fa8bb 100644
--- a/microdroid/system/private/file.te
+++ b/microdroid/system/private/file.te
@@ -4,6 +4,7 @@
 allow cgroup_rc_file tmpfs:filesystem associate;
 allow debugfs_type { debugfs debugfs_tracing debugfs_tracing_debug }:filesystem associate;
 allow dev_type tmpfs:filesystem associate;
+allow extra_apk_file zipfusefs:filesystem associate;
 allow file_type labeledfs:filesystem associate;
 allow file_type tmpfs:filesystem associate;
 allow file_type rootfs:filesystem associate;
diff --git a/microdroid/system/private/file_contexts b/microdroid/system/private/file_contexts
index 8a5f628..933c63f 100644
--- a/microdroid/system/private/file_contexts
+++ b/microdroid/system/private/file_contexts
@@ -171,3 +171,7 @@
 # microdroid doesn't use anr, but tombstoned tries to read this.
 # So marking /data/anr as tombstone_data_file
 /data/anr(/.*)?		u:object_r:tombstone_data_file:s0
+
+#############################
+# Directory for extra apks
+/mnt/extra-apk	u:object_r:extra_apk_file:s0
diff --git a/microdroid/system/private/microdroid_manager.te b/microdroid/system/private/microdroid_manager.te
index b914775..36a5f53 100644
--- a/microdroid/system/private/microdroid_manager.te
+++ b/microdroid/system/private/microdroid_manager.te
@@ -77,4 +77,11 @@
 # that is different from what is recorded in the instance.img file.
 allow microdroid_manager proc_bootconfig:file r_file_perms;
 
+# Allow microdroid_manager to handle extra_apks
+allow microdroid_manager extra_apk_file:dir create_dir_perms;
+
+# Domains other than microdroid can't write extra_apks
+neverallow { domain -microdroid_manager -init -vendor_init } extra_apk_file:file no_w_file_perms;
+neverallow { domain -microdroid_manager -init -vendor_init } extra_apk_file:dir no_w_dir_perms;
+
 neverallow microdroid_manager { file_type fs_type }:file execute_no_trans;
diff --git a/microdroid/system/private/microdroid_payload.te b/microdroid/system/private/microdroid_payload.te
index 7c50db7..5419f52 100644
--- a/microdroid/system/private/microdroid_payload.te
+++ b/microdroid/system/private/microdroid_payload.te
@@ -39,3 +39,6 @@
 allowxperm microdroid_payload vsock_device:chr_file ioctl {
     IOCTL_VM_SOCKETS_GET_LOCAL_CID
 };
+
+# Payload can read extra apks
+r_dir_file(microdroid_payload, extra_apk_file)
diff --git a/microdroid/system/private/odrefresh.te b/microdroid/system/private/odrefresh.te
new file mode 100644
index 0000000..c281896
--- /dev/null
+++ b/microdroid/system/private/odrefresh.te
@@ -0,0 +1,29 @@
+# odrefresh
+type odrefresh, domain, coredomain;
+type odrefresh_exec, system_file_type, exec_type, file_type;
+
+# Run dex2oat in its own sandbox.
+domain_auto_trans(odrefresh, dex2oat_exec, dex2oat)
+
+# Allow odrefresh to kill dex2oat if compilation times out.
+allow odrefresh dex2oat:process sigkill;
+
+# Allow odrefresh to read/write/lookup files/directories on authfs.
+allow odrefresh authfs_fuse:file create_file_perms;
+allow odrefresh authfs_fuse:dir create_dir_perms;
+
+# Allow odrefresh to check the parent directory exists.
+allow odrefresh authfs_data_file:dir { search getattr };
+
+# Allow odrefresh to read /apex/apex-info-list.xml to gather information of
+# the current APEXes.
+allow odrefresh apex_info_file:file r_file_perms;
+
+# Minijail uses pipe for the parent process to signal the child (as a fallback
+# mechanism, since Android does not support minijail's preload).
+# TODO(196109647): We can probably remove this once the minijail preload is
+# supported on Android.
+allow odrefresh compos:fifo_file read;
+
+# Do not audit unused resources from parent processes.
+dontaudit odrefresh compos:fd use;
diff --git a/microdroid/system/private/zipfuse.te b/microdroid/system/private/zipfuse.te
index 04cdadf..da0cd0f 100644
--- a/microdroid/system/private/zipfuse.te
+++ b/microdroid/system/private/zipfuse.te
@@ -37,9 +37,15 @@
 # allow zipfuse to log to the kernel
 allow zipfuse kmsg_device:chr_file w_file_perms;
 
+# allow zipfuse to handle extra apks
+r_dir_file(zipfuse, extra_apk_file)
+allow zipfuse extra_apk_file:dir mounton;
+
 # zipfuse is forked from microdroid_manager
-# TODO(inseob): remove this
 allow zipfuse microdroid_manager:fd use;
 
 # Only microdroid_manager can run zipfuse
 neverallow { domain -microdroid_manager } zipfuse:process { transition dyntransition };
+
+# only zipfuse can mount on extra_apk_file
+neverallow { domain -zipfuse } extra_apk_file:dir mounton;
diff --git a/microdroid/system/public/file.te b/microdroid/system/public/file.te
index c750ccc..5b678ba 100644
--- a/microdroid/system/public/file.te
+++ b/microdroid/system/public/file.te
@@ -10,6 +10,7 @@
 type cgroup_desc_api_file, file_type, system_file_type;
 type cgroup_desc_file, file_type, system_file_type;
 type cgroup_rc_file, file_type;
+type extra_apk_file, file_type;
 type file_contexts_file, file_type, system_file_type;
 type hwservice_contexts_file, file_type, system_file_type;
 type keystore2_key_contexts_file, file_type, system_file_type;
diff --git a/private/compos_fd_server.te b/private/compos_fd_server.te
index 5b11f26..72964c3 100644
--- a/private/compos_fd_server.te
+++ b/private/compos_fd_server.te
@@ -2,18 +2,30 @@
 type compos_fd_server, domain, coredomain;
 
 # Allow access to open fds inherited from odrefresh - read inputs, generate outputs
+# TODO(b/209008712): Remove once migration is done.
 allow compos_fd_server odrefresh:fd use;
 allow compos_fd_server apex_art_data_file:file { getattr read };
-allow compos_fd_server apex_art_staging_data_file:file { getattr read write };
+
+# Allow access to open fds inherited from composd
+allow compos_fd_server composd:fd use;
+
+# Allow creating new files and directory in the staging directory.
+allow compos_fd_server apex_art_staging_data_file:dir create_dir_perms;
+allow compos_fd_server apex_art_staging_data_file:file create_file_perms;
+
 # Use a pipe to signal readiness
+# TODO(b/205750213): Removed odrefresh when we run odrefresh in the VM
 allow compos_fd_server odrefresh:fifo_file write;
+allow compos_fd_server composd:fifo_file write;
 
 # TODO(b/196109647) - remove this when no longer needed by minijail
 allow compos_fd_server odrefresh:fifo_file read;
+allow compos_fd_server composd:fifo_file read;
 
 # Create a listening vsock for the VM to connect back to
 allow compos_fd_server self:vsock_socket { create_socket_perms_no_ioctl listen accept };
 
-# Only odrefresh can enter the domain via exec
-neverallow { domain -odrefresh } compos_fd_server:process transition;
+# Only composd and odrefresh can enter the domain via exec
+# TODO(b/209008712): Remove odrefresh once migration is done.
+neverallow { domain -composd -odrefresh } compos_fd_server:process transition;
 neverallow * compos_fd_server:process dyntransition;
diff --git a/private/composd.te b/private/composd.te
index 41f1a9b..88c4e4a 100644
--- a/private/composd.te
+++ b/private/composd.te
@@ -22,10 +22,14 @@
 allow composd apex_compos_data_file:dir create_dir_perms;
 allow composd apex_compos_data_file:file create_file_perms;
 
-# TODO(b/205750213): Removed these when we run odrefresh in the VM
+# TODO(b/209008712): Removed these when we run odrefresh in the VM
 # Run odrefresh to refresh ART artifacts, and kill it if we need to
 domain_auto_trans(composd, odrefresh_exec, odrefresh)
 allow composd odrefresh:process sigkill;
 
+# Run fd_server in its own domain, and send SIGTERM when finished.
+domain_auto_trans(composd, fd_server_exec, compos_fd_server)
+allow composd compos_fd_server:process signal;
+
 # Read ART's properties
 get_prop(composd, dalvik_config_prop)
diff --git a/private/mediaprovider_app.te b/private/mediaprovider_app.te
index 0e1b1a0..82dcdb2 100644
--- a/private/mediaprovider_app.te
+++ b/private/mediaprovider_app.te
@@ -62,6 +62,7 @@
 allow mediaprovider_app gpu_device:dir search;
 
 dontaudit mediaprovider_app sysfs_vendor_sched:dir search;
+dontaudit mediaprovider_app sysfs_vendor_sched:file w_file_perms;
 
 # bpfprog access for FUSE BPF
 allow mediaprovider_app fs_bpf:dir search;
diff --git a/private/odrefresh.te b/private/odrefresh.te
index e146938..9febf45 100644
--- a/private/odrefresh.te
+++ b/private/odrefresh.te
@@ -70,7 +70,7 @@
 dontaudit odrefresh adbd:unix_stream_socket { getattr read write };
 
 # No other processes should be creating files in the staging area.
-neverallow { domain -init -odrefresh } apex_art_staging_data_file:file open;
+neverallow { domain -init -odrefresh -compos_fd_server } apex_art_staging_data_file:file open;
 
 # No processes other than init, odrefresh and system_server access
 # odrefresh_data_files.
diff --git a/public/fastbootd.te b/public/fastbootd.te
index e167a5e..0c43a89 100644
--- a/public/fastbootd.te
+++ b/public/fastbootd.te
@@ -10,6 +10,10 @@
   # fastbootd can only use HALs in passthrough mode
   passthrough_hal_client_domain(fastbootd, hal_bootctl)
 
+  # fastbootd can use AIDL HALs in binder mode
+  binder_use(fastbootd)
+  hal_client_domain(fastbootd, hal_health)
+
   # Access /dev/usb-ffs/fastbootd/ep0
   allow fastbootd functionfs:dir search;
   allow fastbootd functionfs:file rw_file_perms;
diff --git a/public/hal_nlinterceptor.te b/public/hal_nlinterceptor.te
index 2076de8..1a738a5 100644
--- a/public/hal_nlinterceptor.te
+++ b/public/hal_nlinterceptor.te
@@ -5,4 +5,4 @@
 
 allow hal_nlinterceptor self:global_capability_class_set net_admin;
 allow hal_nlinterceptor self:netlink_generic_socket create_socket_perms_no_ioctl;
-allow hal_nlinterceptor self:netlink_route_socket { nlmsg_readpriv nlmsg_write };
+allow hal_nlinterceptor self:netlink_route_socket { create_socket_perms_no_ioctl nlmsg_readpriv nlmsg_write };
diff --git a/public/recovery.te b/public/recovery.te
index b4b4109..324320b 100755
--- a/public/recovery.te
+++ b/public/recovery.te
@@ -13,6 +13,7 @@
   passthrough_hal_client_domain(recovery, hal_bootctl)
 
   # Recovery can use AIDL HALs in binder mode
+  binder_use(recovery)
   hal_client_domain(recovery, hal_health)
 
   allow recovery self:global_capability_class_set {
diff --git a/public/servicemanager.te b/public/servicemanager.te
index 12004da..a812338 100644
--- a/public/servicemanager.te
+++ b/public/servicemanager.te
@@ -31,7 +31,10 @@
 # Check SELinux permissions.
 selinux_check_access(servicemanager)
 
-# In recovery, log to kmsg.
 recovery_only(`
+  # In recovery, log to kmsg.
   allow servicemanager kmsg_device:chr_file rw_file_perms;
+
+  # Read VINTF files.
+  r_dir_file(servicemanager, rootfs)
 ')