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: I678e199ef03805bb85a8a7ad9f1f7bae0a9fc56a
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index c56380a..83632e4 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -427,12 +427,26 @@
         return -1;
     }
 
+    std::string obbMountDir = StringPrintf("/mnt/user/%d/obb_mount", userId);
+    if (fs_prepare_dir(obbMountDir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
+        PLOG(ERROR) << "Failed to fs_prepare_dir " << obbMountDir;
+        return -1;
+    }
+    const unique_fd obbMountDirFd(
+        TEMP_FAILURE_RETRY(open(obbMountDir.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC)));
+    if (obbMountDirFd.get() < 0) {
+        PLOG(ERROR) << "Failed to open " << obbMountDir;
+        return -1;
+    }
+
     std::unordered_set<appid_t> validAppIds;
     for (auto& package : packageNames) {
         validAppIds.insert(mAppIds[package]);
     }
     std::vector<std::string>& userPackages = mUserPackages[userId];
 
+    std::vector<pid_t> childPids;
+
     struct dirent* de;
     // Poke through all running PIDs look for apps running in userId
     while ((de = readdir(dirp.get()))) {
@@ -508,17 +522,9 @@
                 }
             } else {
                 mountMode = remountMode;
-                std::string obbMountFile = StringPrintf("/mnt/user/%d/package/%s/obb_mount", userId,
-                                                        packagesForUid[0].c_str());
-                if (mountMode == VoldNativeService::REMOUNT_MODE_INSTALLER) {
-                    if (access(obbMountFile.c_str(), F_OK) != 0) {
-                        const unique_fd fd(
-                            TEMP_FAILURE_RETRY(open(obbMountFile.c_str(), O_RDWR | O_CREAT, 0660)));
-                    }
-                } else {
-                    if (access(obbMountFile.c_str(), F_OK) == 0) {
-                        remove(obbMountFile.c_str());
-                    }
+                if (handleMountModeInstaller(mountMode, obbMountDirFd.get(), obbMountDir,
+                                             sandboxId) < 0) {
+                    _exit(1);
                 }
             }
             if (mountMode == VoldNativeService::REMOUNT_MODE_FULL ||
@@ -573,9 +579,12 @@
         if (child == -1) {
             PLOG(ERROR) << "Failed to fork";
         } else {
-            TEMP_FAILURE_RETRY(waitpid(child, nullptr, 0));
+            childPids.push_back(child);
         }
     }
+    for (auto& child : childPids) {
+        TEMP_FAILURE_RETRY(waitpid(child, nullptr, 0));
+    }
     return 0;
 }
 
@@ -597,32 +606,64 @@
     }
 
     std::string obbMountFile =
-        StringPrintf("/mnt/user/%d/package/%s/obb_mount", userId, packagesForUid[0].c_str());
-    if (access(obbMountFile.c_str(), F_OK) == 0) {
+        StringPrintf("/mnt/user/%d/obb_mount/%s", userId, packagesForUid[0].c_str());
+    if (TEMP_FAILURE_RETRY(access(obbMountFile.c_str(), F_OK)) != -1) {
         return VoldNativeService::REMOUNT_MODE_INSTALLER;
+    } else if (errno != ENOENT) {
+        PLOG(ERROR) << "Failed to access " << obbMountFile;
+        return -1;
     }
 
     // Some packages don't have access to external storage and processes belonging to
     // those packages don't have anything mounted at /storage. So, identify those
-    // processes by comparing inode no.s of /mnt/user/%d/package/%s
+    // processes by comparing inode no.s of /mnt/user/%d/package
     // and /storage
-    for (auto& package : packagesForUid) {
-        std::string sandbox = StringPrintf("/mnt/user/%d/package/%s", userId, package.c_str());
-        struct stat sandboxStat;
-        if (TEMP_FAILURE_RETRY(stat(sandbox.c_str(), &sandboxStat)) == -1) {
-            PLOG(ERROR) << "Failed to stat " << sandbox;
-            return -1;
+    std::string sandbox = StringPrintf("/mnt/user/%d/package", userId);
+    struct stat sandboxStat;
+    if (TEMP_FAILURE_RETRY(stat(sandbox.c_str(), &sandboxStat)) == -1) {
+        PLOG(ERROR) << "Failed to stat " << sandbox;
+        return -1;
+    }
+    if (storageSb.st_dev == sandboxStat.st_dev && storageSb.st_ino == sandboxStat.st_ino) {
+        return VoldNativeService::REMOUNT_MODE_WRITE;
+    }
+
+    return VoldNativeService::REMOUNT_MODE_NONE;
+}
+
+int VolumeManager::handleMountModeInstaller(int mountMode, int obbMountDirFd,
+                                            const std::string& obbMountDir,
+                                            const std::string& sandboxId) {
+    if (mountMode == VoldNativeService::REMOUNT_MODE_INSTALLER) {
+        if (TEMP_FAILURE_RETRY(faccessat(obbMountDirFd, sandboxId.c_str(), F_OK, 0)) != -1) {
+            return 0;
+        } else if (errno != ENOENT) {
+            PLOG(ERROR) << "Failed to access " << obbMountDir << "/" << sandboxId;
+            return -errno;
         }
-        if (storageSb.st_dev == sandboxStat.st_dev && storageSb.st_ino == sandboxStat.st_ino) {
-            return VoldNativeService::REMOUNT_MODE_WRITE;
+        const unique_fd fd(
+            TEMP_FAILURE_RETRY(openat(obbMountDirFd, sandboxId.c_str(), O_RDWR | O_CREAT, 0600)));
+        if (fd.get() < 0) {
+            PLOG(ERROR) << "Failed to create " << obbMountDir << "/" << sandboxId;
+            return -errno;
+        }
+    } else {
+        if (TEMP_FAILURE_RETRY(faccessat(obbMountDirFd, sandboxId.c_str(), F_OK, 0)) != -1) {
+            if (TEMP_FAILURE_RETRY(unlinkat(obbMountDirFd, sandboxId.c_str(), 0)) == -1) {
+                PLOG(ERROR) << "Failed to unlink " << obbMountDir << "/" << sandboxId;
+                return -errno;
+            }
+        } else if (errno != ENOENT) {
+            PLOG(ERROR) << "Failed to access " << obbMountDir << "/" << sandboxId;
+            return -errno;
         }
     }
-    return VoldNativeService::REMOUNT_MODE_NONE;
+    return 0;
 }
 
 int VolumeManager::prepareSandboxes(userid_t userId, const std::vector<std::string>& packageNames,
                                     const std::vector<std::string>& visibleVolLabels) {
-    prepareSandboxTargets(userId, packageNames, visibleVolLabels);
+    prepareSandboxTargets(userId, visibleVolLabels);
 
     if (visibleVolLabels.empty()) {
         return 0;
@@ -643,122 +684,58 @@
             return -errno;
         }
     }
-    mountPkgSpecificDirsForRunningProcs(userId, packageNames, visibleVolLabels, -1);
+    if (mountPkgSpecificDirsForRunningProcs(userId, packageNames, visibleVolLabels, -1) < 0) {
+        PLOG(ERROR) << "Failed to setup sandboxes for already running processes";
+        return -errno;
+    }
     return 0;
 }
 
 int VolumeManager::prepareSandboxTargets(userid_t userId,
-                                         const std::vector<std::string>& packageNames,
                                          const std::vector<std::string>& visibleVolLabels) {
     std::string mntTargetRoot = StringPrintf("/mnt/user/%d", userId);
     if (fs_prepare_dir(mntTargetRoot.c_str(), 0751, AID_ROOT, AID_ROOT) != 0) {
-        PLOG(ERROR) << "Failed to fs_prepare_dir %s" << mntTargetRoot;
+        PLOG(ERROR) << "Failed to fs_prepare_dir " << mntTargetRoot;
         return -errno;
     }
+
     StringAppendF(&mntTargetRoot, "/package");
-    if (fs_prepare_dir(mntTargetRoot.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
-        PLOG(ERROR) << "Failed to fs_prepare_dir %s" << mntTargetRoot;
+    if (fs_prepare_dir(mntTargetRoot.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
+        PLOG(ERROR) << "Failed to fs_prepare_dir " << mntTargetRoot;
         return -errno;
     }
 
-    const unique_fd dfd(open(mntTargetRoot.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
-    if (dfd.get() < 0) {
-        PLOG(ERROR) << "Failed to open " << mntTargetRoot;
+    uid_t uid = multiuser_get_uid(userId, AID_EVERYBODY);
+    for (auto& volumeLabel : visibleVolLabels) {
+        std::string sandboxTarget =
+            StringPrintf("%s/%s", mntTargetRoot.c_str(), volumeLabel.c_str());
+        if (fs_prepare_dir(sandboxTarget.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
+            PLOG(ERROR) << "Failed to fs_prepare_dir " << sandboxTarget;
+            return -errno;
+        }
+
+        if (mPrimary && volumeLabel == mPrimary->getLabel() && mPrimary->isEmulated()) {
+            StringAppendF(&sandboxTarget, "/%d", userId);
+            if (fs_prepare_dir(sandboxTarget.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
+                PLOG(ERROR) << "Failed to fs_prepare_dir " << sandboxTarget;
+                return -errno;
+            }
+        }
+    }
+
+    StringAppendF(&mntTargetRoot, "/self");
+    if (fs_prepare_dir(mntTargetRoot.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
+        PLOG(ERROR) << "Failed to fs_prepare_dir " << mntTargetRoot;
         return -errno;
     }
-    for (auto& package : packageNames) {
-        const auto& it = mAppIds.find(package);
-        if (it == mAppIds.end()) {
-            PLOG(ERROR) << "appId is not available for " << package;
-            continue;
-        }
-        appid_t appId = it->second;
-        uid_t uid = multiuser_get_uid(userId, appId);
 
-        if (TEMP_FAILURE_RETRY(faccessat(dfd.get(), package.c_str(), F_OK, 0)) == 0) {
-            continue;
-        } else if (errno != ENOENT) {
-            PLOG(ERROR) << "Failed to faccessat " << mntTargetRoot << "/" << package;
-        }
-        if (TEMP_FAILURE_RETRY(mkdirat(dfd.get(), package.c_str(), 0755)) == -1 && errno != EEXIST) {
-            PLOG(ERROR) << "Failed to mkdirat " << mntTargetRoot << "/" << package;
-            return -errno;
-        }
-        if (TEMP_FAILURE_RETRY(fchownat(dfd.get(), package.c_str(), uid, uid, 0)) == -1) {
-            PLOG(ERROR) << "Failed to fchownat " << mntTargetRoot << "/" << package;
-            return -errno;
-        }
-    }
-    std::string pkgPrimarySource(kEmptyString);
     if (mPrimary) {
-        StringAppendF(&pkgPrimarySource, "%s", mPrimary->getPath().c_str());
+        std::string pkgPrimarySource(mPrimary->getPath());
         if (mPrimary->isEmulated()) {
             StringAppendF(&pkgPrimarySource, "/%d", userId);
         }
-    }
-    for (auto& package : packageNames) {
-        const auto& it = mAppIds.find(package);
-        if (it == mAppIds.end()) {
-            PLOG(ERROR) << "appId is not available for " << package;
-            continue;
-        }
-        appid_t appId = it->second;
-        uid_t uid = multiuser_get_uid(userId, appId);
-
-        std::string pkgMountTarget = StringPrintf("%s/%s", mntTargetRoot.c_str(), package.c_str());
-        const unique_fd packageFd(
-            openat(dfd.get(), package.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
-        if (packageFd.get() < 0) {
-            PLOG(ERROR) << "Failed to openat " << mntTargetRoot << "/" << package;
-            return -errno;
-        }
-        for (auto& volumeLabel : visibleVolLabels) {
-            if (TEMP_FAILURE_RETRY(faccessat(packageFd.get(), volumeLabel.c_str(), F_OK, 0)) == 0) {
-                continue;
-            } else if (errno != ENOENT) {
-                PLOG(ERROR) << "Failed to faccessat " << pkgMountTarget << "/" << volumeLabel;
-            }
-            if (TEMP_FAILURE_RETRY(mkdirat(packageFd.get(), volumeLabel.c_str(), 0755)) == -1 &&
-                errno != EEXIST) {
-                PLOG(ERROR) << "Failed to mkdirat " << pkgMountTarget << "/" << volumeLabel;
-                return -errno;
-            }
-            if (TEMP_FAILURE_RETRY(fchownat(packageFd.get(), volumeLabel.c_str(), uid, uid, 0)) ==
-                -1) {
-                PLOG(ERROR) << "Failed to fchownat " << pkgMountTarget << "/" << volumeLabel;
-                return -errno;
-            }
-
-            if (mPrimary && volumeLabel == mPrimary->getLabel() && mPrimary->isEmulated()) {
-                std::string path =
-                    StringPrintf("%s/%s/%d", pkgMountTarget.c_str(), volumeLabel.c_str(), userId);
-                if (TEMP_FAILURE_RETRY(mkdir(path.c_str(), 0755)) == -1 && errno != EEXIST) {
-                    PLOG(ERROR) << "Failed to mkdir " << path;
-                    return -errno;
-                }
-                if (TEMP_FAILURE_RETRY(chown(path.c_str(), uid, uid)) == -1) {
-                    PLOG(ERROR) << "Failed to chown " << path;
-                }
-            }
-        }
-        if (TEMP_FAILURE_RETRY(faccessat(packageFd.get(), "self", F_OK, 0)) == -1) {
-            if (errno == ENOENT) {
-                if (TEMP_FAILURE_RETRY(mkdirat(packageFd.get(), "self", 0755)) == -1 &&
-                    errno != EEXIST) {
-                    PLOG(ERROR) << "Failed to mkdirat " << pkgMountTarget << "/self";
-                    return -errno;
-                }
-                if (TEMP_FAILURE_RETRY(fchownat(packageFd.get(), "self", uid, uid, 0)) == -1) {
-                    PLOG(ERROR) << "Failed to fchownat " << pkgMountTarget << "/self";
-                    return -errno;
-                }
-            } else {
-                PLOG(ERROR) << "Failed to faccessat " << pkgMountTarget << "/self";
-                return -errno;
-            }
-        }
-        std::string pkgPrimaryTarget = StringPrintf("%s/self/primary", pkgMountTarget.c_str());
-        if (mPrimary && Symlink(pkgPrimarySource, pkgPrimaryTarget) < 0) {
+        StringAppendF(&mntTargetRoot, "/primary");
+        if (Symlink(pkgPrimarySource, mntTargetRoot) < 0) {
             return -errno;
         }
     }
@@ -849,12 +826,10 @@
     if (hasIsolatedStorage()) {
         auto& userPackages = mUserPackages[userId];
         std::string userMntTargetRoot = StringPrintf("/mnt/user/%d", userId);
-        for (auto& package : userPackages) {
-            std::string pkgPrimaryDir = StringPrintf("%s/package/%s/self/primary",
-                                                     userMntTargetRoot.c_str(), package.c_str());
-            if (Unlink(pkgPrimaryDir) < 0) {
-                return -errno;
-            }
+        std::string pkgPrimaryDir =
+            StringPrintf("%s/package/self/primary", userMntTargetRoot.c_str());
+        if (Unlink(pkgPrimaryDir) < 0) {
+            return -errno;
         }
         mUserPackages.erase(userId);
         if (DeleteDirContentsAndDir(userMntTargetRoot) < 0) {
@@ -946,13 +921,6 @@
             }
         }
     }
-    std::string pkgMountTargetDir =
-        StringPrintf("/mnt/user/%d/package/%s", userId, packageName.c_str());
-    std::string pkgPrimaryDir = StringPrintf("%s/self/primary", pkgMountTargetDir.c_str());
-    if (Unlink(pkgPrimaryDir) < 0) {
-        return -errno;
-    }
-    DeleteDirContentsAndDir(pkgMountTargetDir);
 
     return 0;
 }
@@ -974,11 +942,6 @@
         return -errno;
     }
 
-    std::string pkgMountTargetDir =
-        StringPrintf("/mnt/user/%d/package/%s/%s", userId, packageName.c_str(), volLabel.c_str());
-    // It's okay if this fails
-    DeleteDirContentsAndDir(pkgMountTargetDir);
-
     return 0;
 }
 
@@ -1062,16 +1025,13 @@
 
 int VolumeManager::destroySandboxesForVol(android::vold::VolumeBase* vol, userid_t userId) {
     LOG(VERBOSE) << "destroysandboxesForVol: " << vol << " for user=" << userId;
-    const std::vector<std::string>& packageNames = mUserPackages[userId];
-    for (auto& packageName : packageNames) {
-        std::string volSandboxRoot = StringPrintf("/mnt/user/%d/package/%s/%s", userId,
-                                                  packageName.c_str(), vol->getLabel().c_str());
-        if (android::vold::DeleteDirContentsAndDir(volSandboxRoot) < 0) {
-            PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << volSandboxRoot;
-            continue;
-        }
-        LOG(VERBOSE) << "Success: DeleteDirContentsAndDir on " << volSandboxRoot;
+    std::string volSandboxRoot =
+        StringPrintf("/mnt/user/%d/package/%s", userId, vol->getLabel().c_str());
+    if (android::vold::DeleteDirContentsAndDir(volSandboxRoot) < 0) {
+        PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << volSandboxRoot;
+        return -errno;
     }
+    LOG(VERBOSE) << "Success: DeleteDirContentsAndDir on " << volSandboxRoot;
     return 0;
 }