diff --git a/private/app_neverallows.te b/private/app_neverallows.te
index 46b49c274d426da392f0eaecb9e89be1241499af..b8889f74e951a59bd708429df7a0324e04a5a380 100644
--- a/private/app_neverallows.te
+++ b/private/app_neverallows.te
@@ -40,6 +40,16 @@ neverallow { all_untrusted_apps -mediaprovider } property_type:property_service
 # but otherwise disallow untrusted apps from reading this property.
 neverallow { all_untrusted_apps -untrusted_app_25 } net_dns_prop:file read;
 
+# Block calling execve() on files in an apps home directory.
+# This is a W^X violation (loading executable code from a writable
+# home directory). For compatibility, allow for targetApi <= 28.
+# b/112357170
+neverallow {
+  all_untrusted_apps
+  -untrusted_app_25
+  -untrusted_app_27
+} { app_data_file privapp_data_file }:file execute_no_trans;
+
 # Do not allow untrusted apps to be assigned mlstrustedsubject.
 # This would undermine the per-user isolation model being
 # enforced via levelFrom=user in seapp_contexts and the mls
diff --git a/private/seapp_contexts b/private/seapp_contexts
index d0cf2a569d85430edfb7a66c7f59306465683d52..821ef0c2b5f231a0389bd0b3f509553b77937205 100644
--- a/private/seapp_contexts
+++ b/private/seapp_contexts
@@ -114,6 +114,7 @@ user=_app seinfo=media domain=mediaprovider name=android.process.media type=app_
 user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
 user=_app isV2App=true isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=all
 user=_app isPrivApp=true domain=priv_app type=privapp_data_file levelFrom=user
-user=_app minTargetSdkVersion=28 domain=untrusted_app type=app_data_file levelFrom=all
+user=_app minTargetSdkVersion=29 domain=untrusted_app type=app_data_file levelFrom=all
+user=_app minTargetSdkVersion=28 domain=untrusted_app_27 type=app_data_file levelFrom=all
 user=_app minTargetSdkVersion=26 domain=untrusted_app_27 type=app_data_file levelFrom=user
 user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user
diff --git a/private/untrusted_app_25.te b/private/untrusted_app_25.te
index 61c9a817583229acc752e246de7e24bc8ce2543a..d264aaf161a27f044b99d9059d9af57e244437f8 100644
--- a/private/untrusted_app_25.te
+++ b/private/untrusted_app_25.te
@@ -44,3 +44,8 @@ allow untrusted_app_25 proc_tty_drivers:file r_file_perms;
 # Text relocation support for API < 23
 # https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#text-relocations-enforced-for-api-level-23
 allow untrusted_app_25 { apk_data_file app_data_file asec_public_file }:file execmod;
+
+# The ability to call exec() on files in the apps home directories
+# for targetApi<=25. This is also allowed for targetAPIs 26, 27,
+# and 28 in untrusted_app_27.te.
+allow untrusted_app_25 app_data_file:file execute_no_trans;
diff --git a/private/untrusted_app_27.te b/private/untrusted_app_27.te
index 79c776287f5f1766d4543d140cf242871a17bbf0..7b9060d639a637910167a82649613139106f9579 100644
--- a/private/untrusted_app_27.te
+++ b/private/untrusted_app_27.te
@@ -2,7 +2,7 @@
 ### Untrusted_27.
 ###
 ### This file defines the rules for untrusted apps running with
-### 25 < targetSdkVersion <= 27.
+### 25 < targetSdkVersion <= 28.
 ###
 ### This file defines the rules for untrusted apps.
 ### Apps are labeled based on mac_permissions.xml (maps signer and
@@ -26,3 +26,7 @@ app_domain(untrusted_app_27)
 untrusted_app_domain(untrusted_app_27)
 net_domain(untrusted_app_27)
 bluetooth_domain(untrusted_app_27)
+
+# The ability to call exec() on files in the apps home directories
+# for targetApi 26, 27, and 28.
+allow untrusted_app_27 app_data_file:file execute_no_trans;
diff --git a/private/untrusted_app_all.te b/private/untrusted_app_all.te
index 54d278e2c961662e3ef21ee3414ceae57fb7679f..527216def248891dd2bab6ac76a21dfe2255f324 100644
--- a/private/untrusted_app_all.te
+++ b/private/untrusted_app_all.te
@@ -22,7 +22,7 @@
 
 # Some apps ship with shared libraries and binaries that they write out
 # to their sandbox directory and then execute.
-allow untrusted_app_all { app_data_file privapp_data_file }:file { rx_file_perms };
+allow untrusted_app_all { app_data_file privapp_data_file }:file { r_file_perms execute };
 
 # ASEC
 allow untrusted_app_all asec_apk_file:file r_file_perms;