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
This commit is contained in:
Sudheer Shanka 2019-02-21 15:00:11 -08:00
parent af607fa996
commit 727c5fad41
2 changed files with 111 additions and 150 deletions

View file

@ -427,12 +427,26 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
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 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
}
} 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 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
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,17 +606,19 @@ int VolumeManager::getMountModeForRunningProc(const std::vector<std::string>& pa
}
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());
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;
@ -616,13 +627,43 @@ int VolumeManager::getMountModeForRunningProc(const std::vector<std::string>& pa
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;
}
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 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 @@ int VolumeManager::prepareSandboxes(userid_t userId, const std::vector<std::stri
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;
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());
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;
}
uid_t uid = multiuser_get_uid(userId, AID_EVERYBODY);
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;
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()) {
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";
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;
}
}
std::string pkgPrimaryTarget = StringPrintf("%s/self/primary", pkgMountTarget.c_str());
if (mPrimary && Symlink(pkgPrimarySource, pkgPrimaryTarget) < 0) {
}
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;
}
if (mPrimary) {
std::string pkgPrimarySource(mPrimary->getPath());
if (mPrimary->isEmulated()) {
StringAppendF(&pkgPrimarySource, "/%d", userId);
}
StringAppendF(&mntTargetRoot, "/primary");
if (Symlink(pkgPrimarySource, mntTargetRoot) < 0) {
return -errno;
}
}
@ -849,13 +826,11 @@ int VolumeManager::onUserStopped(userid_t userId) {
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());
std::string pkgPrimaryDir =
StringPrintf("%s/package/self/primary", userMntTargetRoot.c_str());
if (Unlink(pkgPrimaryDir) < 0) {
return -errno;
}
}
mUserPackages.erase(userId);
if (DeleteDirContentsAndDir(userMntTargetRoot) < 0) {
PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << userMntTargetRoot;
@ -946,13 +921,6 @@ int VolumeManager::destroySandboxForApp(const std::string& packageName,
}
}
}
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 @@ int VolumeManager::destroySandboxForAppOnVol(const std::string& packageName,
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::onVolumeUnmounted(android::vold::VolumeBase* vol) {
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());
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;
continue;
return -errno;
}
LOG(VERBOSE) << "Success: DeleteDirContentsAndDir on " << volSandboxRoot;
}
return 0;
}

View file

@ -152,8 +152,9 @@ class VolumeManager {
int prepareSandboxes(userid_t userId, const std::vector<std::string>& packageNames,
const std::vector<std::string>& visibleVolLabels);
int prepareSandboxTargets(userid_t userId, const std::vector<std::string>& packageNames,
const std::vector<std::string>& visibleVolLabels);
int prepareSandboxTargets(userid_t userId, const std::vector<std::string>& visibleVolLabels);
int handleMountModeInstaller(int mountMode, int obbMountDirFd, const std::string& obbMountDir,
const std::string& sandboxId);
int mountPkgSpecificDirsForRunningProcs(userid_t userId,
const std::vector<std::string>& packageNames,
const std::vector<std::string>& visibleVolLabels,