Revert "Ensure necessary external storage dirs while creating sandboxes."
This reverts commit 083377e593429a6db7d64de69dcc9d7209f0f66d.
Reason for revert: b/124345887
Change-Id: I388d45fab68b611917464a204269a48bf771ac57
diff --git a/Utils.cpp b/Utils.cpp
index aa2288b..656d706 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -222,26 +222,6 @@
return OK;
}
-status_t CreateDir(const std::string& dir, mode_t mode) {
- struct stat sb;
- if (TEMP_FAILURE_RETRY(stat(dir.c_str(), &sb)) == 0) {
- if (S_ISDIR(sb.st_mode)) {
- return OK;
- } else if (TEMP_FAILURE_RETRY(unlink(dir.c_str())) == -1) {
- PLOG(ERROR) << "Failed to unlink " << dir;
- return -errno;
- }
- } else if (errno != ENOENT) {
- PLOG(ERROR) << "Failed to stat " << dir;
- return -errno;
- }
- if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), mode)) == -1) {
- PLOG(ERROR) << "Failed to mkdir " << dir;
- return -errno;
- }
- return OK;
-}
-
bool FindValue(const std::string& raw, const std::string& key, std::string* value) {
auto qual = key + "=\"";
size_t start = 0;
diff --git a/Utils.h b/Utils.h
index 9a1fa09..574bcd4 100644
--- a/Utils.h
+++ b/Utils.h
@@ -63,9 +63,6 @@
/** Calls unlink(2) at linkpath */
status_t Unlink(const std::string& linkpath);
-/** Creates the given directory if it is not already available */
-status_t CreateDir(const std::string& dir, mode_t mode);
-
bool FindValue(const std::string& raw, const std::string& key, std::string* value);
/* Reads filesystem metadata from device at path */
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 7b08858..db098e3 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -68,14 +68,12 @@
#include "model/ObbVolume.h"
#include "model/StubVolume.h"
-using android::OK;
using android::base::GetBoolProperty;
using android::base::StartsWith;
using android::base::StringAppendF;
using android::base::StringPrintf;
using android::base::unique_fd;
using android::vold::BindMount;
-using android::vold::CreateDir;
using android::vold::DeleteDirContentsAndDir;
using android::vold::Symlink;
using android::vold::Unlink;
@@ -386,14 +384,8 @@
const std::string& packageName, const char* dirName) {
std::string mntSourceDir =
StringPrintf("%s/Android/%s/%s", mntSourceRoot.c_str(), dirName, packageName.c_str());
- if (CreateDir(mntSourceDir, 0755) < 0) {
- return -errno;
- }
std::string mntTargetDir =
StringPrintf("%s/Android/%s/%s", mntTargetRoot.c_str(), dirName, packageName.c_str());
- if (CreateDir(mntTargetDir, 0755) < 0) {
- return -errno;
- }
return BindMount(mntSourceDir, mntTargetDir);
}
@@ -539,9 +531,6 @@
std::string sandboxSource =
StringPrintf("%s/Android/sandbox/%s", mntSource.c_str(), sandboxId.c_str());
- if (CreateDir(sandboxSource, 0755) < 0) {
- continue;
- }
if (BindMount(sandboxSource, mntTarget) < 0) {
continue;
}
@@ -551,9 +540,6 @@
if (UnmountTree(obbTargetDir) < 0) {
continue;
}
- if (!createPkgSpecificDirRoots(mntSource) || !createPkgSpecificDirRoots(mntTarget)) {
- continue;
- }
for (auto& package : packagesForUid) {
mountPkgSpecificDir(mntSource, mntTarget, package, "data");
mountPkgSpecificDir(mntSource, mntTarget, package, "media");
@@ -622,8 +608,6 @@
int VolumeManager::prepareSandboxes(userid_t userId, const std::vector<std::string>& packageNames,
const std::vector<std::string>& visibleVolLabels) {
- prepareSandboxTargets(userId, packageNames, visibleVolLabels);
-
if (visibleVolLabels.empty()) {
return 0;
}
@@ -632,7 +616,8 @@
bool isVolPrimaryEmulated = (volumeLabel == mPrimary->getLabel() && mPrimary->isEmulated());
if (isVolPrimaryEmulated) {
StringAppendF(&volumeRoot, "/%d", userId);
- if (CreateDir(volumeRoot, 0755) < 0) {
+ if (fs_prepare_dir(volumeRoot.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
+ PLOG(ERROR) << "fs_prepare_dir failed on " << volumeRoot;
return -errno;
}
}
@@ -642,127 +627,73 @@
if (sandboxRoot.empty()) {
return -errno;
}
+
+ if (!createPkgSpecificDirRoots(volumeRoot)) {
+ return -errno;
+ }
+
+ std::string mntTargetRoot = StringPrintf("/mnt/user/%d", userId);
+ if (fs_prepare_dir(mntTargetRoot.c_str(), 0751, AID_ROOT, AID_ROOT) != 0) {
+ PLOG(ERROR) << "fs_prepare_dir failed on " << mntTargetRoot;
+ return -errno;
+ }
+ mntTargetRoot.append("/package");
+ if (fs_prepare_dir(mntTargetRoot.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
+ PLOG(ERROR) << "fs_prepare_dir failed on " << mntTargetRoot;
+ return -errno;
+ }
+
+ for (auto& packageName : packageNames) {
+ const auto& it = mAppIds.find(packageName);
+ if (it == mAppIds.end()) {
+ PLOG(ERROR) << "appId is not available for " << packageName;
+ continue;
+ }
+ appid_t appId = it->second;
+ std::string sandboxId = mSandboxIds[appId];
+ uid_t uid = multiuser_get_uid(userId, appId);
+
+ // [1] Create /mnt/runtime/write/emulated/0/Android/sandbox/<sandboxId>
+ // [2] Create /mnt/user/0/package/<packageName>/emulated/0
+ std::string pkgSandboxSourceDir = prepareSandboxSource(uid, sandboxId, sandboxRoot);
+ if (pkgSandboxSourceDir.empty()) {
+ return -errno;
+ }
+ std::string pkgSandboxTargetDir = prepareSandboxTarget(
+ packageName, uid, volumeLabel, mntTargetRoot, isVolPrimaryEmulated);
+ if (pkgSandboxTargetDir.empty()) {
+ return -errno;
+ }
+
+ // Create Android/{data,media,obb}/<packageName> segments at
+ // [1] /mnt/runtime/write/emulated/0/ and
+ // [2] /mnt/runtime/write/emulated/0/Android/sandbox/<sandboxId>/emulated/0/
+ if (!createPkgSpecificDirs(packageName, uid, volumeRoot, pkgSandboxSourceDir)) {
+ return -errno;
+ }
+
+ if (volumeLabel == mPrimary->getLabel()) {
+ // [1] Create /mnt/user/0/package/<packageName>/self/
+ // Link [1] to /storage/emulated/0
+ std::string pkgPrimaryTargetDir =
+ StringPrintf("%s/%s/self", mntTargetRoot.c_str(), packageName.c_str());
+ if (fs_prepare_dir(pkgPrimaryTargetDir.c_str(), 0755, uid, uid) != 0) {
+ PLOG(ERROR) << "Failed to fs_prepare_dir on " << pkgPrimaryTargetDir;
+ return -errno;
+ }
+ StringAppendF(&pkgPrimaryTargetDir, "/primary");
+ std::string primarySource(mPrimary->getPath());
+ if (isVolPrimaryEmulated) {
+ StringAppendF(&primarySource, "/%d", userId);
+ }
+ Symlink(primarySource, pkgPrimaryTargetDir);
+ }
+ }
}
mountPkgSpecificDirsForRunningProcs(userId, packageNames, visibleVolLabels, -1);
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;
- 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;
- 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) {
- 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;
- }
- 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) {
- 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) {
- 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) {
- return -errno;
- }
- }
- return 0;
-}
-
std::string VolumeManager::prepareSubDirs(const std::string& pathPrefix, const std::string& subDirs,
mode_t mode, uid_t uid, gid_t gid) {
std::string path(pathPrefix);
@@ -773,22 +704,78 @@
continue;
}
StringAppendF(&path, "/%s", subDir.c_str());
- if (CreateDir(path, mode) < 0) {
+ if (fs_prepare_dir(path.c_str(), mode, uid, gid) != 0) {
+ PLOG(ERROR) << "fs_prepare_dir failed on " << path;
return kEmptyString;
}
}
return path;
}
+std::string VolumeManager::prepareSandboxSource(uid_t uid, const std::string& sandboxId,
+ const std::string& sandboxRootDir) {
+ std::string sandboxSourceDir(sandboxRootDir);
+ StringAppendF(&sandboxSourceDir, "/%s", sandboxId.c_str());
+ if (fs_prepare_dir(sandboxSourceDir.c_str(), 0755, uid, uid) != 0) {
+ PLOG(ERROR) << "fs_prepare_dir failed on " << sandboxSourceDir;
+ return kEmptyString;
+ }
+ return sandboxSourceDir;
+}
+
+std::string VolumeManager::prepareSandboxTarget(const std::string& packageName, uid_t uid,
+ const std::string& volumeLabel,
+ const std::string& mntTargetRootDir,
+ bool isUserDependent) {
+ std::string segment;
+ if (isUserDependent) {
+ segment = StringPrintf("%s/%s/%d/", packageName.c_str(), volumeLabel.c_str(),
+ multiuser_get_user_id(uid));
+ } else {
+ segment = StringPrintf("%s/%s/", packageName.c_str(), volumeLabel.c_str());
+ }
+ return prepareSubDirs(mntTargetRootDir, segment.c_str(), 0755, uid, uid);
+}
+
+std::string VolumeManager::preparePkgDataSource(const std::string& packageName, uid_t uid,
+ const std::string& dataRootDir) {
+ std::string dataSourceDir = StringPrintf("%s/%s", dataRootDir.c_str(), packageName.c_str());
+ if (fs_prepare_dir(dataSourceDir.c_str(), 0755, uid, uid) != 0) {
+ PLOG(ERROR) << "fs_prepare_dir failed on " << dataSourceDir;
+ return kEmptyString;
+ }
+ return dataSourceDir;
+}
+
bool VolumeManager::createPkgSpecificDirRoots(const std::string& volumeRoot) {
std::string volumeAndroidRoot = StringPrintf("%s/Android", volumeRoot.c_str());
- if (CreateDir(volumeAndroidRoot, 0700) < 0) {
+ if (fs_prepare_dir(volumeAndroidRoot.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
+ PLOG(ERROR) << "fs_prepare_dir failed on " << volumeAndroidRoot;
return false;
}
std::array<std::string, 3> dirs = {"data", "media", "obb"};
for (auto& dir : dirs) {
std::string path = StringPrintf("%s/%s", volumeAndroidRoot.c_str(), dir.c_str());
- if (CreateDir(path, 0700) < 0) {
+ if (fs_prepare_dir(path.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
+ PLOG(ERROR) << "fs_prepare_dir failed on " << path;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool VolumeManager::createPkgSpecificDirs(const std::string& packageName, uid_t uid,
+ const std::string& volumeRoot,
+ const std::string& sandboxDirRoot) {
+ std::array<std::string, 3> dirs = {"data", "media", "obb"};
+ for (auto& dir : dirs) {
+ std::string sourceDir = StringPrintf("%s/Android/%s", volumeRoot.c_str(), dir.c_str());
+ if (prepareSubDirs(sourceDir, packageName, 0755, uid, uid).empty()) {
+ return false;
+ }
+ std::string sandboxSegment =
+ StringPrintf("Android/%s/%s/", dir.c_str(), packageName.c_str());
+ if (prepareSubDirs(sandboxDirRoot, sandboxSegment, 0755, uid, uid).empty()) {
return false;
}
}
diff --git a/VolumeManager.h b/VolumeManager.h
index e369f68..7d299a1 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -152,16 +152,23 @@
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 mountPkgSpecificDirsForRunningProcs(userid_t userId,
const std::vector<std::string>& packageNames,
const std::vector<std::string>& visibleVolLabels,
int remountMode);
int destroySandboxesForVol(android::vold::VolumeBase* vol, userid_t userId);
+ std::string prepareSandboxSource(uid_t uid, const std::string& sandboxId,
+ const std::string& sandboxRootDir);
+ std::string prepareSandboxTarget(const std::string& packageName, uid_t uid,
+ const std::string& volumeLabel,
+ const std::string& mntTargetRootDir, bool isUserDependent);
+ std::string preparePkgDataSource(const std::string& packageName, uid_t uid,
+ const std::string& dataRootDir);
std::string prepareSubDirs(const std::string& pathPrefix, const std::string& subDirs,
mode_t mode, uid_t uid, gid_t gid);
bool createPkgSpecificDirRoots(const std::string& volumeRoot);
+ bool createPkgSpecificDirs(const std::string& packageName, uid_t uid,
+ const std::string& volumeRoot, const std::string& sandboxDirRoot);
int mountPkgSpecificDir(const std::string& mntSourceRoot, const std::string& mntTargetRoot,
const std::string& packageName, const char* dirName);
int destroySandboxForAppOnVol(const std::string& packageName, const std::string& sandboxId,