Update process mount points when appop gets updated.
When an app is started, it's mountmode is dependent on OP_REQUEST_INSTALL_PACKAGES. If user changes the appop grant of an app, we need to update the mounts of any processes running in that app. Bug: 121099965 Test: atest android.appsecurity.cts.ExternalStorageHostTest#testExternalStorageObbGifts Change-Id: I87fee492891d33ccc9fc9e2548114f67d90cc759
This commit is contained in:
parent
2717699b49
commit
817b911ca4
3 changed files with 93 additions and 36 deletions
|
@ -556,24 +556,7 @@ binder::Status VoldNativeService::remountUid(int32_t uid, int32_t remountMode) {
|
||||||
ENFORCE_UID(AID_SYSTEM);
|
ENFORCE_UID(AID_SYSTEM);
|
||||||
ACQUIRE_LOCK;
|
ACQUIRE_LOCK;
|
||||||
|
|
||||||
std::string tmp;
|
return translate(VolumeManager::Instance()->remountUid(uid, remountMode));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binder::Status VoldNativeService::mkdirs(const std::string& path) {
|
binder::Status VoldNativeService::mkdirs(const std::string& path) {
|
||||||
|
|
|
@ -402,7 +402,7 @@ int VolumeManager::mountPkgSpecificDir(const std::string& mntSourceRoot,
|
||||||
|
|
||||||
int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
||||||
userid_t userId, const std::vector<std::string>& packageNames,
|
userid_t userId, const std::vector<std::string>& packageNames,
|
||||||
const std::vector<std::string>& visibleVolLabels) {
|
const std::vector<std::string>& visibleVolLabels, int remountMode) {
|
||||||
// TODO: New processes could be started while traversing over the existing
|
// TODO: New processes could be started while traversing over the existing
|
||||||
// processes which would end up not having the necessary bind mounts. This
|
// processes which would end up not having the necessary bind mounts. This
|
||||||
// issue needs to be fixed, may be by doing multiple passes here?
|
// issue needs to be fixed, may be by doing multiple passes here?
|
||||||
|
@ -497,9 +497,32 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mountMode = getMountModeForRunningProc(packagesForUid, userId, fullWriteSb);
|
int mountMode;
|
||||||
if (mountMode == -1) {
|
if (remountMode == -1) {
|
||||||
_exit(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) {
|
for (auto& volumeLabel : visibleVolLabels) {
|
||||||
|
@ -509,6 +532,13 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
||||||
StringAppendF(&mntSource, "/%d", userId);
|
StringAppendF(&mntSource, "/%d", userId);
|
||||||
StringAppendF(&mntTarget, "/%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) {
|
for (auto& package : packagesForUid) {
|
||||||
mountPkgSpecificDir(mntSource, mntTarget, package, "data");
|
mountPkgSpecificDir(mntSource, mntTarget, package, "data");
|
||||||
mountPkgSpecificDir(mntSource, mntTarget, package, "media");
|
mountPkgSpecificDir(mntSource, mntTarget, package, "media");
|
||||||
|
@ -517,16 +547,14 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mountMode == VoldNativeService::REMOUNT_MODE_INSTALLER) {
|
if (mountMode == VoldNativeService::REMOUNT_MODE_INSTALLER) {
|
||||||
StringAppendF(&mntSource, "/Android/obb");
|
if (TEMP_FAILURE_RETRY(mount(obbSourceDir.c_str(), obbTargetDir.c_str(),
|
||||||
StringAppendF(&mntTarget, "/Android/obb");
|
nullptr, MS_BIND | MS_REC, nullptr)) == -1) {
|
||||||
if (TEMP_FAILURE_RETRY(mount(mntSource.c_str(), mntTarget.c_str(), nullptr,
|
PLOG(ERROR) << "Failed to mount " << obbSourceDir << " to " << obbTargetDir;
|
||||||
MS_BIND | MS_REC, nullptr)) == -1) {
|
|
||||||
PLOG(ERROR) << "Failed to mount " << mntSource << " to " << mntTarget;
|
|
||||||
continue;
|
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) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,7 +721,7 @@ int VolumeManager::prepareSandboxes(userid_t userId, const std::vector<std::stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mountPkgSpecificDirsForRunningProcs(userId, packageNames, visibleVolLabels);
|
mountPkgSpecificDirsForRunningProcs(userId, packageNames, visibleVolLabels, -1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,12 +1092,56 @@ int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>&
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VolumeManager::remountUid(uid_t uid, const std::string& mode) {
|
int VolumeManager::remountUid(uid_t uid, int32_t mountMode) {
|
||||||
// If the isolated storage is enabled, return -1 since in the isolated storage world, there
|
if (!GetBoolProperty(kIsolatedStorage, false)) {
|
||||||
// are no longer any runtime storage permissions, so this shouldn't be called anymore.
|
return remountUidLegacy(uid, mountMode);
|
||||||
if (GetBoolProperty(kIsolatedStorage, false)) {
|
}
|
||||||
|
|
||||||
|
appid_t appId = multiuser_get_app_id(uid);
|
||||||
|
userid_t userId = multiuser_get_user_id(uid);
|
||||||
|
std::vector<std::string> 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<std::string> 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 -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;
|
LOG(DEBUG) << "Remounting " << uid << " as mode " << mode;
|
||||||
|
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
|
|
|
@ -107,7 +107,8 @@ class VolumeManager {
|
||||||
|
|
||||||
int setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol);
|
int setPrimary(const std::shared_ptr<android::vold::VolumeBase>& 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 */
|
/* Reset all internal state, typically during framework boot */
|
||||||
int reset();
|
int reset();
|
||||||
|
@ -153,7 +154,8 @@ class VolumeManager {
|
||||||
const std::vector<std::string>& visibleVolLabels);
|
const std::vector<std::string>& visibleVolLabels);
|
||||||
int mountPkgSpecificDirsForRunningProcs(userid_t userId,
|
int mountPkgSpecificDirsForRunningProcs(userid_t userId,
|
||||||
const std::vector<std::string>& packageNames,
|
const std::vector<std::string>& packageNames,
|
||||||
const std::vector<std::string>& visibleVolLabels);
|
const std::vector<std::string>& visibleVolLabels,
|
||||||
|
int remountMode);
|
||||||
int destroySandboxesForVol(android::vold::VolumeBase* vol, userid_t userId);
|
int destroySandboxesForVol(android::vold::VolumeBase* vol, userid_t userId);
|
||||||
std::string prepareSandboxSource(uid_t uid, const std::string& sandboxId,
|
std::string prepareSandboxSource(uid_t uid, const std::string& sandboxId,
|
||||||
const std::string& sandboxRootDir);
|
const std::string& sandboxRootDir);
|
||||||
|
|
Loading…
Reference in a new issue