Remove sandbox specific bind mounts from root namespace.
Update vold to only create package sandboxes and not do any bind mounts.
After zygote forks, all the necessary bind mounts will be setup for
the process.
Bug: 124009234
Test: manual
Test: atest cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
Test: atest DownloadProviderTests
Test: atest cts/tests/app/src/android/app/cts/DownloadManagerTest.java
Test: atest MediaProviderTests
Test: atest cts/tests/tests/provider/src/android/provider/cts/MediaStore*
Change-Id: Ia42209cb74cbc423bb09c1c51cb7a164f7c568da
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index f600f64..3180d45 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -73,6 +73,11 @@
using android::base::StringAppendF;
using android::base::StringPrintf;
using android::base::unique_fd;
+using android::vold::BindMount;
+using android::vold::DeleteDirContentsAndDir;
+using android::vold::Symlink;
+using android::vold::Unlink;
+using android::vold::UnmountTree;
using android::vold::VoldNativeService;
static const char* kPathUserMount = "/mnt/user";
@@ -369,16 +374,8 @@
}
std::string target(StringPrintf("/mnt/user/%d/primary", userId));
- if (TEMP_FAILURE_RETRY(unlink(target.c_str()))) {
- if (errno != ENOENT) {
- PLOG(WARNING) << "Failed to unlink " << target;
- }
- }
LOG(DEBUG) << "Linking " << source << " to " << target;
- if (TEMP_FAILURE_RETRY(symlink(source.c_str(), target.c_str()))) {
- PLOG(WARNING) << "Failed to link";
- return -errno;
- }
+ Symlink(source, target);
return 0;
}
@@ -389,21 +386,7 @@
StringPrintf("%s/Android/%s/%s", mntSourceRoot.c_str(), dirName, packageName.c_str());
std::string mntTargetDir =
StringPrintf("%s/Android/%s/%s", mntTargetRoot.c_str(), dirName, packageName.c_str());
- if (umount2(mntTargetDir.c_str(), MNT_DETACH) == -1 && errno != EINVAL && errno != ENOENT) {
- PLOG(ERROR) << "Failed to unmount " << mntTargetDir;
- return -1;
- }
- if (TEMP_FAILURE_RETRY(mount(mntSourceDir.c_str(), mntTargetDir.c_str(), nullptr,
- MS_BIND | MS_REC, nullptr)) == -1) {
- PLOG(ERROR) << "Failed to mount " << mntSourceDir << " to " << mntTargetDir;
- return -1;
- }
- if (TEMP_FAILURE_RETRY(
- mount(nullptr, mntTargetDir.c_str(), nullptr, MS_REC | MS_SLAVE, nullptr)) == -1) {
- PLOG(ERROR) << "Failed to set MS_SLAVE at " << mntTargetDir;
- return -1;
- }
- return 0;
+ return BindMount(mntSourceDir, mntTargetDir);
}
int VolumeManager::mountPkgSpecificDirsForRunningProcs(
@@ -545,11 +528,16 @@
StringAppendF(&mntSource, "/%d", userId);
StringAppendF(&mntTarget, "/%d", userId);
}
+
+ std::string sandboxSource =
+ StringPrintf("%s/Android/sandbox/%s", mntSource.c_str(), sandboxId.c_str());
+ if (BindMount(sandboxSource, mntTarget) < 0) {
+ continue;
+ }
+
std::string obbSourceDir = StringPrintf("%s/Android/obb", mntSource.c_str());
std::string obbTargetDir = StringPrintf("%s/Android/obb", mntTarget.c_str());
- if (umount2(obbTargetDir.c_str(), MNT_DETACH) == -1 && errno != EINVAL &&
- errno != ENOENT) {
- PLOG(ERROR) << "Failed to unmount " << obbTargetDir;
+ if (UnmountTree(obbTargetDir) < 0) {
continue;
}
for (auto& package : packagesForUid) {
@@ -560,14 +548,7 @@
}
}
if (mountMode == VoldNativeService::REMOUNT_MODE_INSTALLER) {
- if (TEMP_FAILURE_RETRY(mount(obbSourceDir.c_str(), obbTargetDir.c_str(),
- nullptr, MS_BIND | MS_REC, nullptr)) == -1) {
- PLOG(ERROR) << "Failed to mount " << obbSourceDir << " to " << obbTargetDir;
- continue;
- }
- if (TEMP_FAILURE_RETRY(mount(nullptr, obbTargetDir.c_str(), nullptr,
- MS_REC | MS_SLAVE, nullptr)) == -1) {
- PLOG(ERROR) << "Failed to set MS_SLAVE at " << obbTargetDir.c_str();
+ if (BindMount(obbSourceDir, obbTargetDir) < 0) {
continue;
}
}
@@ -674,7 +655,6 @@
// [1] Create /mnt/runtime/write/emulated/0/Android/sandbox/<sandboxId>
// [2] Create /mnt/user/0/package/<packageName>/emulated/0
- // Mount [1] at [2]
std::string pkgSandboxSourceDir = prepareSandboxSource(uid, sandboxId, sandboxRoot);
if (pkgSandboxSourceDir.empty()) {
return -errno;
@@ -684,23 +664,6 @@
if (pkgSandboxTargetDir.empty()) {
return -errno;
}
- if (umount2(pkgSandboxTargetDir.c_str(), MNT_DETACH) == -1 && errno != EINVAL &&
- errno != ENOENT) {
- PLOG(ERROR) << "Failed to unmount " << pkgSandboxTargetDir;
- return -errno;
- }
- if (TEMP_FAILURE_RETRY(mount(pkgSandboxSourceDir.c_str(), pkgSandboxTargetDir.c_str(),
- nullptr, MS_BIND | MS_REC, nullptr)) == -1) {
- PLOG(ERROR) << "Failed to mount " << pkgSandboxSourceDir << " at "
- << pkgSandboxTargetDir;
- return -errno;
- }
- if (TEMP_FAILURE_RETRY(mount(nullptr, pkgSandboxTargetDir.c_str(), nullptr,
- MS_SLAVE | MS_REC, nullptr)) == -1) {
- PLOG(ERROR) << "Failed to mount " << pkgSandboxSourceDir << " at "
- << pkgSandboxTargetDir;
- return -errno;
- }
// Create Android/{data,media,obb}/<packageName> segments at
// [1] /mnt/runtime/write/emulated/0/ and
@@ -710,9 +673,8 @@
}
if (volumeLabel == mPrimary->getLabel()) {
- // Create [1] /mnt/user/0/package/<packageName>/self/
- // Already created [2] /mnt/user/0/package/<packageName>/emulated/0
- // Mount [2] at [1]
+ // [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) {
@@ -724,16 +686,7 @@
if (isVolPrimaryEmulated) {
StringAppendF(&primarySource, "/%d", userId);
}
- if (TEMP_FAILURE_RETRY(unlink(pkgPrimaryTargetDir.c_str()))) {
- if (errno != ENOENT) {
- PLOG(ERROR) << "Failed to unlink " << pkgPrimaryTargetDir;
- }
- }
- if (TEMP_FAILURE_RETRY(symlink(primarySource.c_str(), pkgPrimaryTargetDir.c_str()))) {
- PLOG(ERROR) << "Failed to link " << primarySource << " at "
- << pkgPrimaryTargetDir;
- return -errno;
- }
+ Symlink(primarySource, pkgPrimaryTargetDir);
}
}
}
@@ -879,17 +832,21 @@
mStartedUsers.erase(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;
+ }
+ }
mUserPackages.erase(userId);
- std::string mntTargetDir = StringPrintf("/mnt/user/%d", userId);
- if (android::vold::UnmountTreeWithPrefix(mntTargetDir) < 0) {
- PLOG(ERROR) << "UnmountTreeWithPrefix on " << mntTargetDir << " failed";
+ if (DeleteDirContentsAndDir(userMntTargetRoot) < 0) {
+ PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << userMntTargetRoot;
return -errno;
}
- if (android::vold::DeleteDirContentsAndDir(mntTargetDir) < 0) {
- PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << mntTargetDir;
- return -errno;
- }
- LOG(VERBOSE) << "Success: DeleteDirContentsAndDir on " << mntTargetDir;
+ LOG(VERBOSE) << "Success: DeleteDirContentsAndDir on " << userMntTargetRoot;
}
return 0;
}
@@ -974,6 +931,14 @@
}
}
}
+ 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;
}
@@ -982,11 +947,6 @@
const std::string& volLabel) {
LOG(VERBOSE) << "destroySandboxOnVol: " << packageName << ", userId=" << userId
<< ", volLabel=" << volLabel;
- std::string pkgSandboxTarget =
- StringPrintf("/mnt/user/%d/package/%s", userId, packageName.c_str());
- if (android::vold::UnmountTreeWithPrefix(pkgSandboxTarget) < 0) {
- PLOG(ERROR) << "UnmountTreeWithPrefix failed on " << pkgSandboxTarget;
- }
std::string sandboxDir = StringPrintf("/mnt/runtime/write/%s", volLabel.c_str());
if (volLabel == mPrimary->getLabel() && mPrimary->isEmulated()) {
@@ -994,10 +954,16 @@
}
StringAppendF(&sandboxDir, "/Android/sandbox/%s", sandboxId.c_str());
- if (android::vold::DeleteDirContentsAndDir(sandboxDir) < 0) {
+ if (DeleteDirContentsAndDir(sandboxDir) < 0) {
PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << sandboxDir;
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;
}
@@ -1085,10 +1051,6 @@
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::UnmountTreeWithPrefix(volSandboxRoot) < 0) {
- PLOG(ERROR) << "UnmountTreeWithPrefix on " << volSandboxRoot << " failed";
- continue;
- }
if (android::vold::DeleteDirContentsAndDir(volSandboxRoot) < 0) {
PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << volSandboxRoot;
continue;
@@ -1290,15 +1252,16 @@
}
updateVirtualDisk();
mAddedUsers.clear();
- mStartedUsers.clear();
mUserPackages.clear();
mAppIds.clear();
mSandboxIds.clear();
mVisibleVolumeIds.clear();
- // For unmounting dirs under /mnt/user/<user-id>/package/<package-name>
- android::vold::UnmountTreeWithPrefix("/mnt/user/");
+ for (userid_t userId : mStartedUsers) {
+ DeleteDirContentsAndDir(StringPrintf("/mnt/user/%d/package", userId));
+ }
+ mStartedUsers.clear();
return 0;
}