diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index c2d4e0b..31890d6 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -556,24 +556,7 @@ binder::Status VoldNativeService::remountUid(int32_t uid, int32_t remountMode) { ENFORCE_UID(AID_SYSTEM); ACQUIRE_LOCK; - std::string tmp; - switch (remountMode) { - case REMOUNT_MODE_NONE: - tmp = "none"; - break; - case REMOUNT_MODE_DEFAULT: - tmp = "default"; - break; - case REMOUNT_MODE_READ: - tmp = "read"; - break; - case REMOUNT_MODE_WRITE: - tmp = "write"; - break; - default: - return error("Unknown mode " + std::to_string(remountMode)); - } - return translate(VolumeManager::Instance()->remountUid(uid, tmp)); + return translate(VolumeManager::Instance()->remountUid(uid, remountMode)); } binder::Status VoldNativeService::mkdirs(const std::string& path) { diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 0137869..f098a09 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -402,7 +402,7 @@ int VolumeManager::mountPkgSpecificDir(const std::string& mntSourceRoot, int VolumeManager::mountPkgSpecificDirsForRunningProcs( userid_t userId, const std::vector& packageNames, - const std::vector& visibleVolLabels) { + const std::vector& visibleVolLabels, int remountMode) { // TODO: New processes could be started while traversing over the existing // processes which would end up not having the necessary bind mounts. This // issue needs to be fixed, may be by doing multiple passes here? @@ -497,9 +497,32 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs( _exit(1); } - int mountMode = getMountModeForRunningProc(packagesForUid, userId, fullWriteSb); - if (mountMode == -1) { - _exit(1); + int mountMode; + if (remountMode == -1) { + mountMode = getMountModeForRunningProc(packagesForUid, userId, fullWriteSb); + if (mountMode == -1) { + _exit(1); + } + } 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 (mountMode == VoldNativeService::REMOUNT_MODE_FULL || + mountMode == VoldNativeService::REMOUNT_MODE_NONE) { + // These mount modes are not going to change dynamically, so don't bother + // unmounting/remounting dirs. + _exit(0); } for (auto& volumeLabel : visibleVolLabels) { @@ -509,6 +532,13 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs( StringAppendF(&mntSource, "/%d", userId); StringAppendF(&mntTarget, "/%d", userId); } + 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; + continue; + } for (auto& package : packagesForUid) { mountPkgSpecificDir(mntSource, mntTarget, package, "data"); mountPkgSpecificDir(mntSource, mntTarget, package, "media"); @@ -517,16 +547,14 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs( } } if (mountMode == VoldNativeService::REMOUNT_MODE_INSTALLER) { - StringAppendF(&mntSource, "/Android/obb"); - StringAppendF(&mntTarget, "/Android/obb"); - if (TEMP_FAILURE_RETRY(mount(mntSource.c_str(), mntTarget.c_str(), nullptr, - MS_BIND | MS_REC, nullptr)) == -1) { - PLOG(ERROR) << "Failed to mount " << mntSource << " to " << mntTarget; + 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, mntTarget.c_str(), nullptr, + if (TEMP_FAILURE_RETRY(mount(nullptr, obbTargetDir.c_str(), nullptr, MS_REC | MS_SLAVE, nullptr)) == -1) { - PLOG(ERROR) << "Failed to set MS_SLAVE at " << mntTarget.c_str(); + PLOG(ERROR) << "Failed to set MS_SLAVE at " << obbTargetDir.c_str(); continue; } } @@ -693,7 +721,7 @@ int VolumeManager::prepareSandboxes(userid_t userId, const std::vector& return 0; } -int VolumeManager::remountUid(uid_t uid, const std::string& mode) { - // If the isolated storage is enabled, return -1 since in the isolated storage world, there - // are no longer any runtime storage permissions, so this shouldn't be called anymore. - if (GetBoolProperty(kIsolatedStorage, false)) { +int VolumeManager::remountUid(uid_t uid, int32_t mountMode) { + if (!GetBoolProperty(kIsolatedStorage, false)) { + return remountUidLegacy(uid, mountMode); + } + + appid_t appId = multiuser_get_app_id(uid); + userid_t userId = multiuser_get_user_id(uid); + std::vector visibleVolLabels; + for (auto& volId : mVisibleVolumeIds) { + auto vol = findVolume(volId); + userid_t mountUserId = vol->getMountUserId(); + if (mountUserId == userId || vol->isEmulated()) { + visibleVolLabels.push_back(vol->getLabel()); + } + } + + // Finding one package with appId is enough + std::vector packageNames; + for (auto it = mAppIds.begin(); it != mAppIds.end(); ++it) { + if (it->second == appId) { + packageNames.push_back(it->first); + break; + } + } + if (packageNames.empty()) { + PLOG(ERROR) << "Failed to find packageName for " << uid; return -1; } + return mountPkgSpecificDirsForRunningProcs(userId, packageNames, visibleVolLabels, mountMode); +} + +int VolumeManager::remountUidLegacy(uid_t uid, int32_t mountMode) { + std::string mode; + switch (mountMode) { + case VoldNativeService::REMOUNT_MODE_NONE: + mode = "none"; + break; + case VoldNativeService::REMOUNT_MODE_DEFAULT: + mode = "default"; + break; + case VoldNativeService::REMOUNT_MODE_READ: + mode = "read"; + break; + case VoldNativeService::REMOUNT_MODE_WRITE: + mode = "write"; + break; + default: + PLOG(ERROR) << "Unknown mode " << std::to_string(mountMode); + return -1; + } LOG(DEBUG) << "Remounting " << uid << " as mode " << mode; DIR* dir; diff --git a/VolumeManager.h b/VolumeManager.h index b1aa954..01a81d1 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -107,7 +107,8 @@ class VolumeManager { int setPrimary(const std::shared_ptr& vol); - int remountUid(uid_t uid, const std::string& mode); + int remountUid(uid_t uid, int32_t remountMode); + int remountUidLegacy(uid_t uid, int32_t remountMode); /* Reset all internal state, typically during framework boot */ int reset(); @@ -153,7 +154,8 @@ class VolumeManager { const std::vector& visibleVolLabels); int mountPkgSpecificDirsForRunningProcs(userid_t userId, const std::vector& packageNames, - const std::vector& visibleVolLabels); + const std::vector& 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);