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:
parent
af607fa996
commit
727c5fad41
2 changed files with 111 additions and 150 deletions
|
@ -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,32 +606,64 @@ 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());
|
||||
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 @@ 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;
|
||||
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 @@ 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());
|
||||
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 @@ 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());
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue