Merge "Don't unmount /storage for early native processes" am: ee9554b2d9 am: b5acb5bfba
am: f1baff6ddd

Change-Id: I7107dd9d24dd07f9c17ea11d24db17db2cd10f12
diff --git a/Android.bp b/Android.bp
index ac4eb59..dca801e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -152,6 +152,9 @@
     shared_libs: [
         "android.hardware.health.storage@1.0",
     ],
+    whole_static_libs: [
+        "com.android.sysprop.apex",
+    ],
 }
 
 cc_binary {
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 91f4597..bfa2065 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -34,6 +34,7 @@
 
 #include <linux/kdev_t.h>
 
+#include <ApexProperties.sysprop.h>
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
@@ -1113,6 +1114,8 @@
     struct stat sb;
     pid_t child;
 
+    static bool apexUpdatable = android::sysprop::ApexProperties::updatable().value_or(false);
+
     if (!(dir = opendir("/proc"))) {
         PLOG(ERROR) << "Failed to opendir";
         return -1;
@@ -1157,6 +1160,26 @@
             goto next;
         }
 
+        if (apexUpdatable) {
+            std::string exeName;
+            // When ro.apex.bionic_updatable is set to true,
+            // some early native processes have mount namespaces that are different
+            // from that of the init. Therefore, above check can't filter them out.
+            // Since the propagation type of / is 'shared', unmounting /storage
+            // for the early native processes affects other processes including
+            // init. Filter out such processes by skipping if a process is a
+            // non-Java process whose UID is < AID_APP_START. (The UID condition
+            // is required to not filter out child processes spawned by apps.)
+            if (!android::vold::Readlinkat(pidFd, "exe", &exeName)) {
+                PLOG(WARNING) << "Failed to read exe name for " << de->d_name;
+                goto next;
+            }
+            if (!StartsWith(exeName, "/system/bin/app_process") && sb.st_uid < AID_APP_START) {
+                LOG(WARNING) << "Skipping due to native system process";
+                goto next;
+            }
+        }
+
         // We purposefully leave the namespace open across the fork
         nsFd = openat(pidFd, "ns/mnt", O_RDONLY);  // not O_CLOEXEC
         if (nsFd < 0) {