diff --git a/private/asan_extract.te b/private/asan_extract.te
new file mode 100644
index 0000000000000000000000000000000000000000..1c20d78ecdb055d2ca26614dc4d5584883715af8
--- /dev/null
+++ b/private/asan_extract.te
@@ -0,0 +1,8 @@
+# type_transition must be private policy the domain_trans rules could stay
+# public, but conceptually should go with this
+# Technically not a daemon but we do want the transition from init domain to
+# asan_extract to occur.
+with_asan(`
+typeattribute asan_extract coredomain;
+init_daemon_domain(asan_extract)
+')
diff --git a/private/file_contexts_asan b/private/file_contexts_asan
index 5e756fc7906cde37761166254d7ce688d4cf1183..d35cd3c947d95fae218bf54ceb2c6e320f4795e9 100644
--- a/private/file_contexts_asan
+++ b/private/file_contexts_asan
@@ -2,3 +2,4 @@
 /data/asan/system/lib64(/.*)?              u:object_r:system_file:s0
 /data/asan/vendor/lib(/.*)?                u:object_r:system_file:s0
 /data/asan/vendor/lib64(/.*)?              u:object_r:system_file:s0
+/system/bin/asan_extract       u:object_r:asan_extract_exec:s0
diff --git a/private/property_contexts b/private/property_contexts
index c205e594cfb28f7f27567da5cbf5d3b67682ad39..498bab8f4890348d76025e6de03e3e602ddc1e4c 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -112,3 +112,6 @@ wlan.                   u:object_r:wifi_prop:s0
 
 # hwservicemanager properties
 hwservicemanager.       u:object_r:hwservicemanager_prop:s0
+
+# ASAN install trigger
+asan.restore_reboot  u:object_r:asan_reboot_prop:s0
diff --git a/public/asan_extract.te b/public/asan_extract.te
new file mode 100644
index 0000000000000000000000000000000000000000..6d0de6cf1fd517067cb55aeb27874028a4e98dfb
--- /dev/null
+++ b/public/asan_extract.te
@@ -0,0 +1,36 @@
+# asan_extract
+#
+# This command set moves the artifact corresponding to the current slot
+# from /data/ota to /data/dalvik-cache.
+
+with_asan(`
+  type asan_extract, domain, coredomain;
+  type asan_extract_exec, exec_type, file_type;
+
+  # Allow asan_extract to execute itself using #!/system/bin/sh
+  allow asan_extract shell_exec:file rx_file_perms;
+
+  # We execute log, rm, gzip and tar.
+  allow asan_extract toolbox_exec:file rx_file_perms;
+  allow asan_extract system_file:file execute_no_trans;
+
+  # asan_extract deletes old /data/lib.
+  allow asan_extract system_file:dir { open read remove_name rmdir write };
+  allow asan_extract system_file:file unlink;
+
+  # asan_extract untars ASAN libraries into /data.
+  allow asan_extract system_data_file:dir create_dir_perms ;
+  allow asan_extract system_data_file:{ file lnk_file } create_file_perms ;
+
+  # Relabel the libraries with restorecon.
+  allow asan_extract file_contexts_file:file r_file_perms;
+  allow asan_extract system_data_file:{ dir file } relabelfrom;
+  allow asan_extract system_file:dir { relabelto setattr };
+  allow asan_extract system_file:file relabelto;
+
+  # Restorecon will actually already try to run with sanitized libraries (libpackagelistparser).
+  allow asan_extract system_data_file:file execute;
+
+  # We use asan.restore_reboot to signal a reboot is required.
+  set_prop(asan_extract, asan_reboot_prop)
+')
diff --git a/public/domain.te b/public/domain.te
index 30b3a98e0b998f4405a399c1a14dac9b8c172cc7..4a0ee76c84dd373e0ef9aca34df425c54cb8fa1f 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -300,6 +300,7 @@ neverallow { domain -kernel -init -recovery -vold -zygote -update_engine -otapre
 neverallow {
     domain
     -appdomain
+    with_asan(`-asan_extract')
     -dumpstate
     -shell
     userdebug_or_eng(`-su')
@@ -336,9 +337,9 @@ neverallow { domain -init } properties_device:file { no_w_file_perms no_x_file_p
 neverallow { domain -init } properties_serial:file { no_w_file_perms no_x_file_perms };
 
 # Only recovery should be doing writes to /system
-neverallow { domain -recovery } { system_file exec_type }:dir_file_class_set
+neverallow { domain -recovery with_asan(`-asan_extract') } { system_file exec_type }:dir_file_class_set
     { create write setattr relabelfrom append unlink link rename };
-neverallow { domain -recovery -kernel } { system_file exec_type }:dir_file_class_set relabelto;
+neverallow { domain -recovery -kernel with_asan(`-asan_extract') } { system_file exec_type }:dir_file_class_set relabelto;
 
 # Don't allow mounting on top of /system files or directories
 neverallow * exec_type:dir_file_class_set mounton;
@@ -739,6 +740,7 @@ neverallow {
   -system_app
   -init
   -installd # for relabelfrom and unlink, check for this in explicit neverallow
+  with_asan(`-asan_extract')
 } system_data_file:file no_w_file_perms;
 # do not grant anything greater than r_file_perms and relabelfrom unlink
 # to installd
diff --git a/public/property.te b/public/property.te
index a3f5a1e4393045aa7525bb4a1c776844b8f69e07..69106036251fb1a14d523aa9c5de1e33b6c9adb1 100644
--- a/public/property.te
+++ b/public/property.te
@@ -1,3 +1,4 @@
+type asan_reboot_prop, property_type;
 type audio_prop, property_type, core_property_type;
 type boottime_prop, property_type;
 type bluetooth_prop, property_type;