Remove sandbox specific bind mounts from root namespace.

Update vold to only create package sandboxes and not do any bind mounts.
After zygote forks, all the necessary bind mounts will be setup for
the process.

Bug: 124009234
Test: manual
Test: atest cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
Test: atest DownloadProviderTests
Test: atest cts/tests/app/src/android/app/cts/DownloadManagerTest.java
Test: atest MediaProviderTests
Test: atest cts/tests/tests/provider/src/android/provider/cts/MediaStore*

Change-Id: Ibd4af79b385e20228a0e9ce4446f14ead87e228e
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index d2ab053..9e97e37 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -526,11 +526,12 @@
                                   @Nullable String packageName,
                                   @Nullable String[] packagesForUid,
                                   @Nullable String[] visibleVols,
+                                  @Nullable String sandboxId,
                                   @Nullable String[] zygoteArgs) {
         return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, packageName,
-                    packagesForUid, visibleVols, /*useBlastulaPool=*/ true, zygoteArgs);
+                    packagesForUid, visibleVols, sandboxId, /*useBlastulaPool=*/ true, zygoteArgs);
     }
 
     /** @hide */
@@ -547,11 +548,12 @@
                                   @Nullable String packageName,
                                   @Nullable String[] packagesForUid,
                                   @Nullable String[] visibleVols,
+                                  @Nullable String sandboxId,
                                   @Nullable String[] zygoteArgs) {
         return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, packageName,
-                    packagesForUid, visibleVols, /*useBlastulaPool=*/ false, zygoteArgs);
+                    packagesForUid, visibleVols, sandboxId, /*useBlastulaPool=*/ false, zygoteArgs);
     }
 
     /**
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index e94ad2b..ee3d354 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -324,13 +324,15 @@
                                                   @Nullable String packageName,
                                                   @Nullable String[] packagesForUid,
                                                   @Nullable String[] visibleVols,
+                                                  @Nullable String sandboxId,
                                                   boolean useBlastulaPool,
                                                   @Nullable String[] zygoteArgs) {
         try {
             return startViaZygote(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/false,
-                    packageName, packagesForUid, visibleVols, useBlastulaPool, zygoteArgs);
+                    packageName, packagesForUid, visibleVols, sandboxId,
+                    useBlastulaPool, zygoteArgs);
         } catch (ZygoteStartFailedEx ex) {
             Log.e(LOG_TAG,
                     "Starting VM process through Zygote failed");
@@ -541,6 +543,7 @@
                                                       @Nullable String packageName,
                                                       @Nullable String[] packagesForUid,
                                                       @Nullable String[] visibleVols,
+                                                      @Nullable String sandboxId,
                                                       boolean useBlastulaPool,
                                                       @Nullable String[] extraArgs)
                                                       throws ZygoteStartFailedEx {
@@ -639,6 +642,10 @@
             argsForZygote.add(sb.toString());
         }
 
+        if (sandboxId != null) {
+            argsForZygote.add("--sandbox-id=" + sandboxId);
+        }
+
         argsForZygote.add(processClass);
 
         if (extraArgs != null) {
@@ -1014,7 +1021,7 @@
                     gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
                     abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
                     true /* startChildZygote */, null /* packageName */,
-                    null /* packagesForUid */, null /* visibleVolumes */,
+                    null /* packagesForUid */, null /* visibleVolumes */, null /* sandboxId */,
                     false /* useBlastulaPool */, extraArgs);
         } catch (ZygoteStartFailedEx ex) {
             throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index f521c68..03b2c2c 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -132,4 +132,9 @@
      * @param listener The listener that will be notified on reset events.
      */
     public abstract void addResetListener(ResetListener listener);
+
+    /**
+     * Return the sandboxId for the given package on external storage.
+     */
+    public abstract String getSandboxId(String packageName);
 }
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 8b669d5..40d7868 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -254,14 +254,14 @@
     public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
             int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
-            String packageName, String[] packagesForUID, String[] visibleVolIDs) {
+            String packageName, String[] packagesForUID, String[] visibleVolIDs, String sandboxId) {
         ZygoteHooks.preFork();
         // Resets nice priority for zygote process.
         resetNicePriority();
         int pid = nativeForkAndSpecialize(
                 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                 fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName,
-                packagesForUID, visibleVolIDs);
+                packagesForUID, visibleVolIDs, sandboxId);
         // Enable tracing as soon as possible for the child process.
         if (pid == 0) {
             Trace.setTracingEnabled(true, runtimeFlags);
@@ -276,7 +276,8 @@
     private static native int nativeForkAndSpecialize(int uid, int gid, int[] gids,
             int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
             int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
-            String appDataDir, String packageName, String[] packagesForUID, String[] visibleVolIDs);
+            String appDataDir, String packageName, String[] packagesForUID, String[] visibleVolIDs,
+            String sandboxId);
 
     /**
      * Specialize a Blastula instance.  The current VM must have been started
@@ -302,11 +303,11 @@
     public static void specializeBlastula(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, int mountExternal, String seInfo, String niceName,
             boolean startChildZygote, String instructionSet, String appDataDir, String packageName,
-            String[] packagesForUID, String[] visibleVolIDs) {
+            String[] packagesForUID, String[] visibleVolIDs, String sandboxId) {
 
         nativeSpecializeBlastula(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
                                  niceName, startChildZygote, instructionSet, appDataDir,
-                                 packageName, packagesForUID, visibleVolIDs);
+                                 packageName, packagesForUID, visibleVolIDs, sandboxId);
 
         // Enable tracing as soon as possible for the child process.
         Trace.setTracingEnabled(true, runtimeFlags);
@@ -326,7 +327,7 @@
     private static native void nativeSpecializeBlastula(int uid, int gid, int[] gids,
             int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
             boolean startChildZygote, String instructionSet, String appDataDir, String packageName,
-            String[] packagesForUID, String[] visibleVolIDs);
+            String[] packagesForUID, String[] visibleVolIDs, String sandboxId);
 
     /**
      * Called to do any initialization before starting an application.
@@ -638,7 +639,7 @@
                            args.mRuntimeFlags, rlimits, args.mMountExternal,
                            args.mSeInfo, args.mNiceName, args.mStartChildZygote,
                            args.mInstructionSet, args.mAppDataDir, args.mPackageName,
-                           args.mPackagesForUid, args.mVisibleVolIds);
+                           args.mPackagesForUid, args.mVisibleVolIds, args.mSandboxId);
 
         if (args.mNiceName != null) {
             Process.setArgV0(args.mNiceName);
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
index 24a08ca..e6bcd37 100644
--- a/core/java/com/android/internal/os/ZygoteArguments.java
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -119,6 +119,9 @@
     /** from --visible-vols */
     String[] mVisibleVolIds;
 
+    /** from --sandbox-id */
+    String mSandboxId;
+
     /**
      * Any args after and including the first non-option arg (or after a '--')
      */
@@ -385,6 +388,11 @@
                 mPackagesForUid = arg.substring(arg.indexOf('=') + 1).split(",");
             } else if (arg.startsWith("--visible-vols=")) {
                 mVisibleVolIds = arg.substring(arg.indexOf('=') + 1).split(",");
+            } else if (arg.startsWith("--sandbox-id=")) {
+                if (mSandboxId != null) {
+                    throw new IllegalArgumentException("Duplicate arg specified");
+                }
+                mSandboxId = arg.substring(arg.indexOf('=') + 1);
             } else {
                 break;
             }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 9ba56b8..1468b50 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -258,7 +258,7 @@
                 parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                 parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                 parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mPackageName,
-                parsedArgs.mPackagesForUid, parsedArgs.mVisibleVolIds);
+                parsedArgs.mPackagesForUid, parsedArgs.mVisibleVolIds, parsedArgs.mSandboxId);
 
         try {
             if (pid == 0) {
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 0ef4f87..bbe89d6 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -620,15 +620,10 @@
 static void BindMount(const std::string& sourceDir, const std::string& targetDir,
                       fail_fn_t fail_fn) {
     if (TEMP_FAILURE_RETRY(mount(sourceDir.c_str(), targetDir.c_str(), nullptr,
-                                 MS_BIND | MS_REC, nullptr)) == -1) {
+                                 MS_BIND, nullptr)) == -1) {
         fail_fn(CREATE_ERROR("Failed to mount %s to %s: %s",
                              sourceDir.c_str(), targetDir.c_str(), strerror(errno)));
     }
-
-    if (TEMP_FAILURE_RETRY(mount(nullptr, targetDir.c_str(), nullptr,
-                                 MS_SLAVE | MS_REC, nullptr)) == -1) {
-        fail_fn(CREATE_ERROR("Failed to set MS_SLAVE for %s", targetDir.c_str()));
-    }
 }
 
 static void MountPkgSpecificDir(const std::string& mntSourceRoot,
@@ -646,24 +641,8 @@
 
 static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames,
                                    const std::vector<std::string>& volumeLabels,
-                                   bool mountAllObbs, userid_t userId, fail_fn_t fail_fn) {
-    if (volumeLabels.size() > 0) {
-        std::string sandboxDataDir = StringPrintf("/storage/%s", volumeLabels[0].c_str());
-        if (volumeLabels[0] == "emulated") {
-            StringAppendF(&sandboxDataDir, "/%d", userId);
-        }
-        StringAppendF(&sandboxDataDir, "/Android/data/%s", packageNames[0].c_str());
-        struct stat sb;
-        if (TEMP_FAILURE_RETRY(lstat(sandboxDataDir.c_str(), &sb)) == -1) {
-            if (errno == ENOENT) {
-                ALOGD("Sandbox not fully prepared for %s", sandboxDataDir.c_str());
-                return;
-            } else {
-                fail_fn(CREATE_ERROR("Failed to lstat %s: %s",
-                                     sandboxDataDir.c_str(), strerror(errno)));
-            }
-        }
-    }
+                                   bool mountAllObbs, const std::string& sandboxId,
+                                   userid_t userId, fail_fn_t fail_fn) {
     for (auto& label : volumeLabels) {
         std::string mntSource = StringPrintf("/mnt/runtime/write/%s", label.c_str());
         std::string mntTarget = StringPrintf("/storage/%s", label.c_str());
@@ -672,6 +651,10 @@
             StringAppendF(&mntTarget, "/%d", userId);
         }
 
+        std::string sandboxSource = StringPrintf("%s/Android/sandbox/%s",
+            mntSource.c_str(), sandboxId.c_str());
+        BindMount(sandboxSource, mntTarget, fail_fn);
+
         for (auto& package : packageNames) {
             MountPkgSpecificDir(mntSource, mntTarget, package, "data", fail_fn);
             MountPkgSpecificDir(mntSource, mntTarget, package, "media", fail_fn);
@@ -693,7 +676,8 @@
 static void MountEmulatedStorage(uid_t uid, jint mount_mode,
         bool force_mount_namespace, const std::string& package_name,
         const std::vector<std::string>& packages_for_uid,
-        const std::vector<std::string>& visible_vol_ids, fail_fn_t fail_fn) {
+        const std::vector<std::string>& visible_vol_ids, const std::string& sandbox_id,
+        fail_fn_t fail_fn) {
     // See storage config details at http://source.android.com/tech/storage/
 
     String8 storageSource;
@@ -744,7 +728,7 @@
                                      strerror(errno)));
             }
         } else {
-            if (package_name.empty()) {
+            if (package_name.empty() || sandbox_id.empty()) {
                 return;
             }
 
@@ -790,7 +774,7 @@
             // care of by vold later.
             if (sandboxAlreadyCreated) {
                 PreparePkgSpecificDirs(packages_for_uid, visible_vol_ids,
-                    mount_mode == MOUNT_EXTERNAL_INSTALLER, user_id, fail_fn);
+                    mount_mode == MOUNT_EXTERNAL_INSTALLER, sandbox_id, user_id, fail_fn);
             }
         }
     } else {
@@ -1127,7 +1111,7 @@
                              bool is_child_zygote, jstring managed_instruction_set,
                              jstring managed_app_data_dir, jstring managed_package_name,
                              jobjectArray managed_pacakges_for_uid,
-                             jobjectArray managed_visible_vol_ids) {
+                             jobjectArray managed_visible_vol_ids, jstring managed_sandbox_id) {
   const char* process_name = is_system_server ? "system_server" : "zygote";
   auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
   auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
@@ -1137,6 +1121,7 @@
   auto instruction_set = extract_fn(managed_instruction_set);
   auto app_data_dir = extract_fn(managed_app_data_dir);
   auto package_name = extract_fn(managed_package_name);
+  auto sandbox_id = extract_fn(managed_sandbox_id);
 
   // Keep capabilities across UID change, unless we're staying root.
   if (uid != 0) {
@@ -1179,7 +1164,7 @@
       value_or(std::vector<std::string>());
 
   MountEmulatedStorage(uid, mount_external, use_native_bridge, package_name.value(),
-                       packages_for_uid, visible_vol_ids, fail_fn);
+                       packages_for_uid, visible_vol_ids, sandbox_id.value_or(""), fail_fn);
 
   // If this zygote isn't root, it won't be able to create a process group,
   // since the directory is owned by root.
@@ -1479,7 +1464,7 @@
         jint mount_external, jstring se_info, jstring nice_name,
         jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
         jstring instruction_set, jstring app_data_dir, jstring package_name,
-        jobjectArray packages_for_uid, jobjectArray visible_vol_ids) {
+        jobjectArray packages_for_uid, jobjectArray visible_vol_ids, jstring sandbox_id) {
     jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
 
     if (UNLIKELY(managed_fds_to_close == nullptr)) {
@@ -1511,7 +1496,7 @@
                        capabilities, capabilities,
                        mount_external, se_info, nice_name, false,
                        is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
-                       package_name, packages_for_uid, visible_vol_ids);
+                       package_name, packages_for_uid, visible_vol_ids, sandbox_id);
     }
     return pid;
 }
@@ -1537,7 +1522,7 @@
       SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                        permitted_capabilities, effective_capabilities,
                        MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
-                       false, nullptr, nullptr, nullptr, nullptr, nullptr);
+                       false, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
   } else if (pid > 0) {
       // The zygote process checks whether the child process has died or not.
       ALOGI("System server process %d has been created", pid);
@@ -1691,14 +1676,15 @@
     jint runtime_flags, jobjectArray rlimits,
     jint mount_external, jstring se_info, jstring nice_name,
     jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir,
-    jstring package_name, jobjectArray packages_for_uid, jobjectArray visible_vol_ids) {
+    jstring package_name, jobjectArray packages_for_uid, jobjectArray visible_vol_ids,
+    jstring sandbox_id) {
   jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
 
   SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                    capabilities, capabilities,
                    mount_external, se_info, nice_name, false,
                    is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
-                   package_name, packages_for_uid, visible_vol_ids);
+                   package_name, packages_for_uid, visible_vol_ids, sandbox_id);
 }
 
 /**
@@ -1789,7 +1775,7 @@
     { "nativeSecurityInit", "()V",
       (void *) com_android_internal_os_Zygote_nativeSecurityInit },
     { "nativeForkAndSpecialize",
-      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)I",
+      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I",
       (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
     { "nativeForkSystemServer", "(II[II[[IJJ)I",
       (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
@@ -1804,7 +1790,7 @@
     { "nativeForkBlastula", "(II[I)I",
       (void *) com_android_internal_os_Zygote_nativeForkBlastula },
     { "nativeSpecializeBlastula",
-      "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
+      "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V",
       (void *) com_android_internal_os_Zygote_nativeSpecializeBlastula },
     { "nativeGetSocketFDs", "(Z)V",
       (void *) com_android_internal_os_Zygote_nativeGetSocketFDs },