Create a new mount mode for installer packages.
New external storage mount mode for installers so that they can access obb dirs of all apps. Bug: 111789719 Test: atest android.appsecurity.cts#testExternalStorageObbGifts Change-Id: Iab112f0273806f8f812f14d6691bbe71dff42d83
This commit is contained in:
parent
042dfdde7b
commit
03992e3741
3 changed files with 62 additions and 33 deletions
|
@ -73,6 +73,7 @@ using android::base::StartsWith;
|
|||
using android::base::StringAppendF;
|
||||
using android::base::StringPrintf;
|
||||
using android::base::unique_fd;
|
||||
using android::vold::VoldNativeService;
|
||||
|
||||
static const char* kPathUserMount = "/mnt/user";
|
||||
static const char* kPathVirtualDisk = "/data/misc/vold/virtual_disk";
|
||||
|
@ -496,40 +497,11 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
|||
_exit(1);
|
||||
}
|
||||
|
||||
struct stat storageSb;
|
||||
if (TEMP_FAILURE_RETRY(stat("/storage", &storageSb)) == -1) {
|
||||
PLOG(ERROR) << "Failed to stat /storage";
|
||||
int mountMode = getMountModeForRunningProc(packagesForUid, userId, fullWriteSb);
|
||||
if (mountMode == -1) {
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
// Some packages have access to full external storage, identify processes belonging
|
||||
// to those packages by comparing inode no.s of /mnt/runtime/write and /storage
|
||||
if (storageSb.st_dev == fullWriteSb.st_dev && storageSb.st_ino == fullWriteSb.st_ino) {
|
||||
_exit(0);
|
||||
} else {
|
||||
// Some packages don't have access to external storage and processes belonging to
|
||||
// those packages don't have anything mounted at /storage. So, identify those
|
||||
// processes by comparing inode no.s of /mnt/user/%d/package/%s
|
||||
// and /storage
|
||||
std::string pkgStorageSource;
|
||||
for (auto& package : packagesForUid) {
|
||||
std::string sandbox =
|
||||
StringPrintf("/mnt/user/%d/package/%s", userId, package.c_str());
|
||||
struct stat s;
|
||||
if (TEMP_FAILURE_RETRY(stat(sandbox.c_str(), &s)) == -1) {
|
||||
PLOG(ERROR) << "Failed to stat " << sandbox;
|
||||
_exit(1);
|
||||
}
|
||||
if (storageSb.st_dev == s.st_dev && storageSb.st_ino == s.st_ino) {
|
||||
pkgStorageSource = sandbox;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pkgStorageSource.empty()) {
|
||||
_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& volumeLabel : visibleVolLabels) {
|
||||
std::string mntSource = StringPrintf("/mnt/runtime/write/%s", volumeLabel.c_str());
|
||||
std::string mntTarget = StringPrintf("/storage/%s", volumeLabel.c_str());
|
||||
|
@ -540,7 +512,23 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
|||
for (auto& package : packagesForUid) {
|
||||
mountPkgSpecificDir(mntSource, mntTarget, package, "data");
|
||||
mountPkgSpecificDir(mntSource, mntTarget, package, "media");
|
||||
mountPkgSpecificDir(mntSource, mntTarget, package, "obb");
|
||||
if (mountMode != VoldNativeService::REMOUNT_MODE_INSTALLER) {
|
||||
mountPkgSpecificDir(mntSource, mntTarget, package, "obb");
|
||||
}
|
||||
}
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
if (TEMP_FAILURE_RETRY(mount(nullptr, mntTarget.c_str(), nullptr,
|
||||
MS_REC | MS_SLAVE, nullptr)) == -1) {
|
||||
PLOG(ERROR) << "Failed to set MS_SLAVE at " << mntTarget.c_str();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
_exit(0);
|
||||
|
@ -555,6 +543,44 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int VolumeManager::getMountModeForRunningProc(const std::vector<std::string>& packagesForUid,
|
||||
userid_t userId, struct stat& mntWriteStat) {
|
||||
struct stat storageSb;
|
||||
if (TEMP_FAILURE_RETRY(stat("/storage", &storageSb)) == -1) {
|
||||
PLOG(ERROR) << "Failed to stat /storage";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Some packages have access to full external storage, identify processes belonging
|
||||
// to those packages by comparing inode no.s of /mnt/runtime/write and /storage
|
||||
if (storageSb.st_dev == mntWriteStat.st_dev && storageSb.st_ino == mntWriteStat.st_ino) {
|
||||
return VoldNativeService::REMOUNT_MODE_FULL;
|
||||
}
|
||||
|
||||
std::string obbMountFile =
|
||||
StringPrintf("/mnt/user/%d/package/%s/obb_mount", userId, packagesForUid[0].c_str());
|
||||
if (access(obbMountFile.c_str(), F_OK) == 0) {
|
||||
return VoldNativeService::REMOUNT_MODE_INSTALLER;
|
||||
}
|
||||
|
||||
// Some packages don't have access to external storage and processes belonging to
|
||||
// those packages don't have anything mounted at /storage. So, identify those
|
||||
// processes by comparing inode no.s of /mnt/user/%d/package/%s
|
||||
// and /storage
|
||||
for (auto& package : packagesForUid) {
|
||||
std::string sandbox = StringPrintf("/mnt/user/%d/package/%s", userId, package.c_str());
|
||||
struct stat sandboxStat;
|
||||
if (TEMP_FAILURE_RETRY(stat(sandbox.c_str(), &sandboxStat)) == -1) {
|
||||
PLOG(ERROR) << "Failed to stat " << sandbox;
|
||||
return -1;
|
||||
}
|
||||
if (storageSb.st_dev == sandboxStat.st_dev && storageSb.st_ino == sandboxStat.st_ino) {
|
||||
return VoldNativeService::REMOUNT_MODE_WRITE;
|
||||
}
|
||||
}
|
||||
return VoldNativeService::REMOUNT_MODE_NONE;
|
||||
}
|
||||
|
||||
int VolumeManager::prepareSandboxes(userid_t userId, const std::vector<std::string>& packageNames,
|
||||
const std::vector<std::string>& visibleVolLabels) {
|
||||
if (visibleVolLabels.empty()) {
|
||||
|
|
|
@ -171,6 +171,8 @@ class VolumeManager {
|
|||
const std::string& packageName, const char* dirName);
|
||||
int destroySandboxForAppOnVol(const std::string& packageName, const std::string& sandboxId,
|
||||
userid_t userId, const std::string& volLabel);
|
||||
int getMountModeForRunningProc(const std::vector<std::string>& packagesForUid, userid_t userId,
|
||||
struct stat& mntWriteStat);
|
||||
|
||||
void handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk);
|
||||
void handleDiskChanged(dev_t device);
|
||||
|
|
|
@ -151,7 +151,8 @@ interface IVold {
|
|||
const int REMOUNT_MODE_DEFAULT = 1;
|
||||
const int REMOUNT_MODE_READ = 2;
|
||||
const int REMOUNT_MODE_WRITE = 3;
|
||||
const int REMOUNT_MODE_FULL = 4;
|
||||
const int REMOUNT_MODE_INSTALLER = 4;
|
||||
const int REMOUNT_MODE_FULL = 5;
|
||||
|
||||
const int VOLUME_STATE_UNMOUNTED = 0;
|
||||
const int VOLUME_STATE_CHECKING = 1;
|
||||
|
|
Loading…
Reference in a new issue