diff --git a/domain.te b/domain.te
index 2922da6835c0c066230284bdfea3da29ac793a1f..c3ed601c2ddd4f4c62deac779bdf25f24596915a 100644
--- a/domain.te
+++ b/domain.te
@@ -249,7 +249,7 @@ neverallow { domain -init -ueventd } device:chr_file { open read write };
 # Limit what domains can mount filesystems or change their mount flags.
 # sdcard_type / vfat is exempt as a larger set of domains need
 # this capability, including device-specific domains.
-neverallow { domain -kernel -init -recovery -vold -zygote } { fs_type -sdcard_type }:filesystem { mount remount relabelfrom relabelto };
+neverallow { domain -kernel -init -recovery -vold -zygote -update_engine } { fs_type -sdcard_type }:filesystem { mount remount relabelfrom relabelto };
 
 #
 # Assert that, to the extent possible, we're not loading executable content from
@@ -263,7 +263,7 @@ neverallow {
     userdebug_or_eng(`-su')
     -system_server
     -zygote
-} { file_type -system_file -exec_type }:file execute;
+} { file_type -system_file -exec_type -postinstall_file }:file execute;
 neverallow {
     domain
     -appdomain # for oemfs
diff --git a/file.te b/file.te
index 1998669af012f2842b059d69a1060c2f634851bc..a2963a5da3cfccbe4b4266c016d761b3505368d2 100644
--- a/file.te
+++ b/file.te
@@ -109,6 +109,11 @@ type storage_file, file_type;
 type mnt_media_rw_stub_file, file_type;
 type storage_stub_file, file_type;
 
+# /postinstall: Mount point used by update_engine to run postinstall.
+type postinstall_mnt_dir, file_type;
+# Files inside the /postinstall mountpoint are all labeled as postinstall_file.
+type postinstall_file, file_type, exec_type;
+
 # /data/misc subdirectories
 type adb_keys_file, file_type, data_file_type;
 type audio_data_file, file_type, data_file_type;
@@ -216,6 +221,7 @@ allow file_type tmpfs:filesystem associate;
 allow file_type rootfs:filesystem associate;
 allow dev_type tmpfs:filesystem associate;
 allow app_fuse_file app_fusefs:filesystem associate;
+allow postinstall_file self:filesystem associate;
 
 # It's a bug to assign the file_type attribute and fs_type attribute
 # to any type. Do not allow it.
diff --git a/file_contexts b/file_contexts
index 0a7565949599f22372e97d806e4ec22348ae388b..d98f25d7797ea26e2758986db144797ff9d25f26 100644
--- a/file_contexts
+++ b/file_contexts
@@ -23,6 +23,7 @@
 /acct               u:object_r:cgroup:s0
 /config             u:object_r:rootfs:s0
 /mnt                u:object_r:tmpfs:s0
+/postinstall        u:object_r:postinstall_mnt_dir:s0
 /proc               u:object_r:rootfs:s0
 /root               u:object_r:rootfs:s0
 /sys                u:object_r:sysfs:s0
diff --git a/init.te b/init.te
index 1baeeeeb67c4963281c50a3ee559bcbe60e59cd5..047ea73d8ea8fa7bde1109d71122e9eaf0a909e7 100644
--- a/init.te
+++ b/init.te
@@ -88,8 +88,9 @@ allow init contextmount_type:filesystem relabelto;
 allow init contextmount_type:dir r_dir_perms;
 allow init contextmount_type:notdevfile_class_set r_file_perms;
 
-# restorecon /adb_keys or any other rootfs files to a more specific type.
-allow init rootfs:file relabelfrom;
+# restorecon /adb_keys or any other rootfs files and directories to a more
+# specific type.
+allow init rootfs:{ dir file } relabelfrom;
 
 # mkdir, symlink, write, rm/rmdir, chown/chmod, restorecon/restorecon_recursive from init.rc files.
 # chown/chmod require open+read+setattr required for open()+fchown/fchmod().
diff --git a/postinstall.te b/postinstall.te
new file mode 100644
index 0000000000000000000000000000000000000000..8afc56128dd7acf783f2b9c5f3c247d52e6ee92e
--- /dev/null
+++ b/postinstall.te
@@ -0,0 +1,20 @@
+# Domain where the postinstall program runs during the update.
+# Extend the permissions in this domain to allow this program to access other
+# files needed by the specific device on your device's sepolicy directory.
+type postinstall, domain;
+
+# Allow postinstall to write to its stdout/stderr when redirected via pipes to
+# update_engine.
+allow postinstall update_engine:fd use;
+allow postinstall update_engine:fifo_file rw_file_perms;
+
+# Allow postinstall to read and execute directories and files in the same
+# mounted location.
+allow postinstall postinstall_file:file rx_file_perms;
+allow postinstall postinstall_file:lnk_file r_file_perms;
+allow postinstall postinstall_file:dir r_dir_perms;
+
+# Allow postinstall to execute the shell or other system executables.
+allow postinstall shell_exec:file rx_file_perms;
+allow postinstall system_file:file rx_file_perms;
+allow postinstall toolbox_exec:file rx_file_perms;
diff --git a/update_engine.te b/update_engine.te
index 39b99361ad35ddee05544ba16e9fdab3e265396e..cf614e6a0883399a1c60b8155a6351d6267b9067 100644
--- a/update_engine.te
+++ b/update_engine.te
@@ -13,6 +13,9 @@ allow update_engine kmsg_device:chr_file w_file_perms;
 allow update_engine update_engine_exec:file rx_file_perms;
 wakelock_use(update_engine);
 
+# Ignore these denials.
+dontaudit update_engine kernel:process setsched;
+
 # Allow using persistent storage in /data/misc/update_engine.
 allow update_engine update_engine_data_file:dir { create_dir_perms };
 allow update_engine update_engine_data_file:file { create_file_perms };
@@ -27,6 +30,25 @@ allow update_engine system_block_device:blk_file rw_file_perms;
 # Don't allow kernel module loading, just silence the logs.
 dontaudit update_engine kernel:system module_request;
 
+# Allow update_engine to mount on the /postinstall directory and reset the
+# labels on the mounted filesystem to postinstall_file.
+allow update_engine postinstall_mnt_dir:dir mounton;
+allow update_engine postinstall_file:filesystem { mount unmount relabelfrom relabelto };
+allow update_engine labeledfs:filesystem relabelfrom;
+
+# Allow update_engine to read and execute postinstall_file.
+allow update_engine postinstall_file:file rx_file_perms;
+allow update_engine postinstall_file:lnk_file r_file_perms;
+allow update_engine postinstall_file:dir r_dir_perms;
+
+# The postinstall program is run by update_engine and will always be tagged as a
+# postinstall_file regardless of its attributes in the new system.
+domain_auto_trans(update_engine, postinstall_file, postinstall)
+
+# A postinstall program is typically a shell script (with a #!), so we allow
+# to execute those.
+allow update_engine shell_exec:file rx_file_perms;
+
 # Register the service to perform Binder IPC.
 binder_use(update_engine)
 allow update_engine update_engine_service:service_manager { add };