Avoid creating /mnt/user/<userId>/package/<packageName> for all pkgs.

Bug: 124466384
Test: manual
Test: atest cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
Test: atest cts/tests/app/src/android/app/cts/DownloadManagerTest.java
Test: atest cts/tests/tests/provider/src/android/provider/cts/MediaStore*
Change-Id: I025c2ce647cd3263da45800c5cb728d2f0f08c96
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 15ceca9..4c5b284 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -613,17 +613,13 @@
     }
 }
 
-static void CreatePkgSandboxTarget(uid_t uid, const std::string& package_name, fail_fn_t fail_fn) {
-    // Create /mnt/user/0/package/<package-name>
-    userid_t user_id = multiuser_get_user_id(uid);
-    std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", user_id);
+static void CreatePkgSandboxTarget(userid_t userId, fail_fn_t fail_fn) {
+    // Create /mnt/user/0/package
+    std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", userId);
     CreateDir(pkg_sandbox_dir, 0751, AID_ROOT, AID_ROOT, fail_fn);
 
     StringAppendF(&pkg_sandbox_dir, "/package");
-    CreateDir(pkg_sandbox_dir, 0700, AID_ROOT, AID_ROOT, fail_fn);
-
-    StringAppendF(&pkg_sandbox_dir, "/%s", package_name.c_str());
-    CreateDir(pkg_sandbox_dir, 0755, uid, uid, fail_fn);
+    CreateDir(pkg_sandbox_dir, 0755, AID_ROOT, AID_ROOT, fail_fn);
 }
 
 static void BindMount(const std::string& sourceDir, const std::string& targetDir,
@@ -650,25 +646,25 @@
     BindMount(mntSourceDir, mntTargetDir, fail_fn);
 }
 
-static void CreateSubDirs(int dirfd, const std::string& parentDirPath,
+static void CreateSubDirs(int parentFd, const std::string& parentPath,
                           const std::vector<std::string>& subDirs,
                           fail_fn_t fail_fn) {
     for (auto& dirName : subDirs) {
         struct stat sb;
-        if (TEMP_FAILURE_RETRY(fstatat(dirfd, dirName.c_str(), &sb, 0)) == 0) {
+        if (TEMP_FAILURE_RETRY(fstatat(parentFd, dirName.c_str(), &sb, 0)) == 0) {
             if (S_ISDIR(sb.st_mode)) {
                 continue;
-            } else if (TEMP_FAILURE_RETRY(unlinkat(dirfd, dirName.c_str(), 0)) == -1) {
+            } else if (TEMP_FAILURE_RETRY(unlinkat(parentFd, dirName.c_str(), 0)) == -1) {
                 fail_fn(CREATE_ERROR("Failed to unlinkat on %s/%s: %s",
-                        parentDirPath.c_str(), dirName.c_str(), strerror(errno)));
+                        parentPath.c_str(), dirName.c_str(), strerror(errno)));
             }
         } else if (errno != ENOENT) {
             fail_fn(CREATE_ERROR("Failed to fstatat on %s/%s: %s",
-                    parentDirPath.c_str(), dirName.c_str(), strerror(errno)));
+                    parentPath.c_str(), dirName.c_str(), strerror(errno)));
         }
-        if (TEMP_FAILURE_RETRY(mkdirat(dirfd, dirName.c_str(), 0700)) == -1 && errno != EEXIST) {
+        if (TEMP_FAILURE_RETRY(mkdirat(parentFd, dirName.c_str(), 0700)) == -1 && errno != EEXIST) {
             fail_fn(CREATE_ERROR("Failed to mkdirat on %s/%s: %s",
-                    parentDirPath.c_str(), dirName.c_str(), strerror(errno)));
+                    parentPath.c_str(), dirName.c_str(), strerror(errno)));
         }
     }
 }
@@ -754,6 +750,9 @@
         if (TEMP_FAILURE_RETRY(access(mntSource.c_str(), F_OK)) == -1) {
             ALOGE("Can't access %s: %s", mntSource.c_str(), strerror(errno));
             continue;
+        } else if (TEMP_FAILURE_RETRY(access(mntTarget.c_str(), F_OK)) == -1) {
+            ALOGE("Can't access %s: %s", mntTarget.c_str(), strerror(errno));
+            continue;
         }
 
         // Ensure /mnt/runtime/write/emulated/0/Android/{data,media,obb}
@@ -782,6 +781,39 @@
     }
 }
 
+static void handleMountModeInstaller(int mountMode,
+                                     userid_t userId,
+                                     const std::string& sandboxId,
+                                     fail_fn_t fail_fn) {
+    std::string obbMountDir = StringPrintf("/mnt/user/%d/obb_mount", userId);
+    std::string obbMountFile = StringPrintf("%s/%s", obbMountDir.c_str(), sandboxId.c_str());
+    if (mountMode == MOUNT_EXTERNAL_INSTALLER) {
+        if (TEMP_FAILURE_RETRY(access(obbMountFile.c_str(), F_OK)) != -1) {
+            return;
+        } else if (errno != ENOENT) {
+            fail_fn(CREATE_ERROR("Failed to access %s: %s", obbMountFile.c_str(), strerror(errno)));
+        }
+        if (fs_prepare_dir(obbMountDir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
+            fail_fn(CREATE_ERROR("Failed to fs_prepare_dir %s: %s",
+                    obbMountDir.c_str(), strerror(errno)));
+        }
+        const android::base::unique_fd fd(TEMP_FAILURE_RETRY(
+                open(obbMountFile.c_str(), O_RDWR | O_CREAT, 0600)));
+        if (fd.get() < 0) {
+            fail_fn(CREATE_ERROR("Failed to create %s: %s", obbMountFile.c_str(), strerror(errno)));
+        }
+    } else {
+        if (TEMP_FAILURE_RETRY(access(obbMountFile.c_str(), F_OK)) != -1) {
+            if (TEMP_FAILURE_RETRY(unlink(obbMountFile.c_str())) == -1) {
+                fail_fn(CREATE_ERROR("Failed to unlink %s: %s",
+                        obbMountDir.c_str(), strerror(errno)));
+            }
+        } else if (errno != ENOENT) {
+            fail_fn(CREATE_ERROR("Failed to access %s: %s", obbMountFile.c_str(), strerror(errno)));
+        }
+    }
+}
+
 // Create a private mount namespace and bind mount appropriate emulated
 // storage for the given user.
 static void MountEmulatedStorage(uid_t uid, jint mount_mode,
@@ -844,48 +876,19 @@
             }
 
             userid_t user_id = multiuser_get_user_id(uid);
-            std::string pkgSandboxDir =
-                StringPrintf("/mnt/user/%d/package/%s", user_id, package_name.c_str());
-            bool sandboxAlreadyCreated = true;
-            if (TEMP_FAILURE_RETRY(access(pkgSandboxDir.c_str(), F_OK)) == -1) {
-                if (errno == ENOENT) {
-                    ALOGD("Sandbox not yet created for %s", pkgSandboxDir.c_str());
-                    sandboxAlreadyCreated = false;
-                    CreatePkgSandboxTarget(uid, package_name, fail_fn);
-                } else {
-                    fail_fn(CREATE_ERROR("Failed to access %s: %s",
-                                         pkgSandboxDir.c_str(), strerror(errno)));
-                }
-            }
+            CreatePkgSandboxTarget(user_id, fail_fn);
 
+            std::string pkgSandboxDir = StringPrintf("/mnt/user/%d/package", user_id);
             if (TEMP_FAILURE_RETRY(mount(pkgSandboxDir.c_str(), "/storage",
                                          nullptr, MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
                 fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
                                      pkgSandboxDir.c_str(), strerror(errno)));
             }
 
-            if (TEMP_FAILURE_RETRY(access("/storage/obb_mount", F_OK)) == 0) {
-                if (mount_mode != MOUNT_EXTERNAL_INSTALLER) {
-                    remove("/storage/obb_mount");
-                }
-            } else {
-                if (mount_mode == MOUNT_EXTERNAL_INSTALLER) {
-                    int fd =
-                        TEMP_FAILURE_RETRY(open("/storage/obb_mount", O_RDWR | O_CREAT, 0660));
-                    if (fd == -1) {
-                        fail_fn(CREATE_ERROR("Couldn't create /storage/obb_mount: %s",
-                                             strerror(errno)));
-                    }
-                    close(fd);
-                }
-            }
-            // If the sandbox was already created by vold, only then set up the bind mounts for
-            // pkg specific directories. Otherwise, leave as is and bind mounts will be taken
-            // care of by vold later.
-            if (sandboxAlreadyCreated) {
-                PreparePkgSpecificDirs(packages_for_uid, visible_vol_ids,
-                    mount_mode == MOUNT_EXTERNAL_INSTALLER, sandbox_id, user_id, uid, fail_fn);
-            }
+            handleMountModeInstaller(mount_mode, user_id, sandbox_id, fail_fn);
+
+            PreparePkgSpecificDirs(packages_for_uid, visible_vol_ids,
+                mount_mode == MOUNT_EXTERNAL_INSTALLER, sandbox_id, user_id, uid, fail_fn);
         }
     } else {
         if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage", nullptr,
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index cd9d84c..a5eab85 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2811,6 +2811,7 @@
 
     @Override
     public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) {
+        Slog.d(TAG, "unlockUserKey: " + userId);
         enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
 
         if (StorageManager.isFileEncryptedNativeOrEmulated()) {
@@ -4056,6 +4057,11 @@
 
         @Override
         public String[] getVisibleVolumesForUser(int userId) {
+            synchronized (mLock) {
+                if (!ArrayUtils.contains(mSystemUnlockedUsers, userId)) {
+                    return EmptyArray.STRING;
+                }
+            }
             final ArrayList<String> visibleVolsForUser = new ArrayList<>();
             for (int i = mVisibleVols.size() - 1; i >= 0; --i) {
                 final VolumeInfo vol = mVisibleVols.get(i);