diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 5544c81..fbdce7e 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -886,17 +886,28 @@ binder::Status VoldNativeService::destroyUserStorage(const std::unique_ptrmountExternalStorageForApp(packageName, appId, - sandboxId, userId)); + return translate( + VolumeManager::Instance()->prepareSandboxForApp(packageName, appId, sandboxId, userId)); +} + +binder::Status VoldNativeService::destroySandboxForApp(const std::string& packageName, + int32_t appId, const std::string& sandboxId, + int32_t userId) { + ENFORCE_UID(AID_SYSTEM); + CHECK_ARGUMENT_PACKAGE_NAME(packageName); + CHECK_ARGUMENT_SANDBOX_ID(sandboxId); + ACQUIRE_LOCK; + + return translate( + VolumeManager::Instance()->destroySandboxForApp(packageName, appId, sandboxId, userId)); } binder::Status VoldNativeService::startCheckpoint(int32_t retry, bool* _aidl_return) { diff --git a/VoldNativeService.h b/VoldNativeService.h index 6e14964..a79c38a 100644 --- a/VoldNativeService.h +++ b/VoldNativeService.h @@ -116,8 +116,10 @@ class VoldNativeService : public BinderService, public os::Bn binder::Status destroyUserStorage(const std::unique_ptr& uuid, int32_t userId, int32_t flags); - binder::Status mountExternalStorageForApp(const std::string& packageName, int32_t appId, - const std::string& sandboxId, int32_t userId); + binder::Status prepareSandboxForApp(const std::string& packageName, int32_t appId, + const std::string& sandboxId, int32_t userId); + binder::Status destroySandboxForApp(const std::string& packageName, int32_t appId, + const std::string& sandboxId, int32_t userId); binder::Status startCheckpoint(int32_t retry, bool* _aidl_return); binder::Status needsCheckpoint(bool* _aidl_return); diff --git a/VolumeManager.cpp b/VolumeManager.cpp index ec18694..8b70867 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -834,8 +834,8 @@ int VolumeManager::addSandboxIds(const std::vector& appIds, return 0; } -int VolumeManager::mountExternalStorageForApp(const std::string& packageName, appid_t appId, - const std::string& sandboxId, userid_t userId) { +int VolumeManager::prepareSandboxForApp(const std::string& packageName, appid_t appId, + const std::string& sandboxId, userid_t userId) { if (!GetBoolProperty(kIsolatedStorage, false)) { return 0; } else if (mStartedUsers.find(userId) == mStartedUsers.end()) { @@ -843,7 +843,7 @@ int VolumeManager::mountExternalStorageForApp(const std::string& packageName, ap // be created when the user starts. return 0; } - LOG(VERBOSE) << "mountExternalStorageForApp: " << packageName << ", appId=" << appId + LOG(VERBOSE) << "prepareSandboxForApp: " << packageName << ", appId=" << appId << ", sandboxId=" << sandboxId << ", userId=" << userId; mUserPackages[userId].push_back(packageName); mAppIds[packageName] = appId; @@ -860,6 +860,71 @@ int VolumeManager::mountExternalStorageForApp(const std::string& packageName, ap return prepareSandboxes(userId, {packageName}, visibleVolLabels); } +int VolumeManager::destroySandboxForApp(const std::string& packageName, appid_t appId, + const std::string& sandboxId, userid_t userId) { + if (!GetBoolProperty(kIsolatedStorage, false)) { + return 0; + } + LOG(VERBOSE) << "destroySandboxForApp: " << packageName << ", appId=" << appId + << ", sandboxId=" << sandboxId << ", userId=" << userId; + auto& userPackages = mUserPackages[userId]; + std::remove(userPackages.begin(), userPackages.end(), packageName); + // If the package is not uninstalled in any other users, remove appId and sandboxId + // corresponding to it from the internal state. + bool installedInAnyUser = false; + for (auto& it : mUserPackages) { + auto& packages = it.second; + if (std::find(packages.begin(), packages.end(), packageName) != packages.end()) { + installedInAnyUser = true; + break; + } + } + if (!installedInAnyUser) { + mAppIds.erase(packageName); + mSandboxIds.erase(appId); + } + + std::vector visibleVolLabels; + for (auto& volId : mVisibleVolumeIds) { + auto vol = findVolume(volId); + userid_t mountUserId = vol->getMountUserId(); + if (mountUserId == userId || vol->isEmulated()) { + if (destroySandboxForAppOnVol(packageName, sandboxId, userId, vol->getLabel()) < 0) { + return -errno; + } + } + } + return 0; +} + +int VolumeManager::destroySandboxForAppOnVol(const std::string& packageName, + const std::string& sandboxId, userid_t userId, + 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::UnmountTree(pkgSandboxTarget)) { + PLOG(ERROR) << "UnmountTree failed on " << pkgSandboxTarget; + } + + std::string sandboxDir = StringPrintf("/mnt/runtime/write/%s", volLabel.c_str()); + if (volLabel == mPrimary->getLabel() && mPrimary->isEmulated()) { + StringAppendF(&sandboxDir, "/%d", userId); + } + if (StartsWith(sandboxId, "shared:")) { + StringAppendF(&sandboxDir, "/Android/sandbox/shared/%s", sandboxId.substr(7).c_str()); + } else { + StringAppendF(&sandboxDir, "/Android/sandbox/%s", sandboxId.c_str()); + } + + if (android::vold::DeleteDirContentsAndDir(sandboxDir) < 0) { + PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << sandboxDir; + return -errno; + } + return 0; +} + int VolumeManager::onSecureKeyguardStateChanged(bool isShowing) { mSecureKeyguardShowing = isShowing; if (!mSecureKeyguardShowing) { diff --git a/VolumeManager.h b/VolumeManager.h index 5d211db..8982d8f 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -96,8 +96,10 @@ class VolumeManager { int addAppIds(const std::vector& packageNames, const std::vector& appIds); int addSandboxIds(const std::vector& appIds, const std::vector& sandboxIds); - int mountExternalStorageForApp(const std::string& packageName, appid_t appId, - const std::string& sandboxId, userid_t userId); + int prepareSandboxForApp(const std::string& packageName, appid_t appId, + const std::string& sandboxId, userid_t userId); + int destroySandboxForApp(const std::string& packageName, appid_t appId, + const std::string& sandboxId, userid_t userId); int onVolumeMounted(android::vold::VolumeBase* vol); int onVolumeUnmounted(android::vold::VolumeBase* vol); @@ -162,6 +164,8 @@ class VolumeManager { 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, + userid_t userId, const std::string& volLabel); void handleDiskAdded(const std::shared_ptr& disk); void handleDiskChanged(dev_t device); diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl index f825a30..ac65b54 100644 --- a/binder/android/os/IVold.aidl +++ b/binder/android/os/IVold.aidl @@ -99,8 +99,10 @@ interface IVold { int storageFlags); void destroyUserStorage(@nullable @utf8InCpp String uuid, int userId, int storageFlags); - void mountExternalStorageForApp(in @utf8InCpp String packageName, int appId, - in @utf8InCpp String sandboxId, int userId); + void prepareSandboxForApp(in @utf8InCpp String packageName, int appId, + in @utf8InCpp String sandboxId, int userId); + void destroySandboxForApp(in @utf8InCpp String packageName, int appId, + in @utf8InCpp String sandboxId, int userId); boolean startCheckpoint(int retry); boolean needsCheckpoint();