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;
}