Create a new MOUNT_EXTERNAL_LEGACY storage mode.
Apps that are already installed on the device before isolated_storage feature is enabled will be granted MOUNT_EXTERNAL_LEGACY mode. In this mode, /mnt/runtime/write will be mounted at /storage giving them same level of access as in P. A new mount directory /mnt/runtime/full is also created which will be used for mounting at /storage for apps started with MOUNT_EXTERNAL_FULL mode. This will allow apps with WRITE_MEDIA_STORAGE permission to read/write anywhere on the secondary devices without needing to bypass sdcardfs. Bug: 121277410 Test: manual Test: atest android.appsecurity.cts.ExternalStorageHostTest Change-Id: Icc1ff9da35545692daedef7173d7c89290dd2766
This commit is contained in:
parent
811de623a0
commit
5504901bf0
4 changed files with 29 additions and 38 deletions
|
@ -425,8 +425,13 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat fullWriteSb;
|
struct stat mntFullSb;
|
||||||
if (TEMP_FAILURE_RETRY(stat("/mnt/runtime/write", &fullWriteSb)) == -1) {
|
struct stat mntWriteSb;
|
||||||
|
if (TEMP_FAILURE_RETRY(stat("/mnt/runtime/full", &mntFullSb)) == -1) {
|
||||||
|
PLOG(ERROR) << "Failed to stat /mnt/runtime/full";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (TEMP_FAILURE_RETRY(stat("/mnt/runtime/write", &mntWriteSb)) == -1) {
|
||||||
PLOG(ERROR) << "Failed to stat /mnt/runtime/write";
|
PLOG(ERROR) << "Failed to stat /mnt/runtime/write";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -505,7 +510,8 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
||||||
|
|
||||||
int mountMode;
|
int mountMode;
|
||||||
if (remountMode == -1) {
|
if (remountMode == -1) {
|
||||||
mountMode = getMountModeForRunningProc(packagesForUid, userId, fullWriteSb);
|
mountMode =
|
||||||
|
getMountModeForRunningProc(packagesForUid, userId, mntWriteSb, mntFullSb);
|
||||||
if (mountMode == -1) {
|
if (mountMode == -1) {
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
@ -525,6 +531,7 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mountMode == VoldNativeService::REMOUNT_MODE_FULL ||
|
if (mountMode == VoldNativeService::REMOUNT_MODE_FULL ||
|
||||||
|
mountMode == VoldNativeService::REMOUNT_MODE_LEGACY ||
|
||||||
mountMode == VoldNativeService::REMOUNT_MODE_NONE) {
|
mountMode == VoldNativeService::REMOUNT_MODE_NONE) {
|
||||||
// These mount modes are not going to change dynamically, so don't bother
|
// These mount modes are not going to change dynamically, so don't bother
|
||||||
// unmounting/remounting dirs.
|
// unmounting/remounting dirs.
|
||||||
|
@ -578,7 +585,8 @@ int VolumeManager::mountPkgSpecificDirsForRunningProcs(
|
||||||
}
|
}
|
||||||
|
|
||||||
int VolumeManager::getMountModeForRunningProc(const std::vector<std::string>& packagesForUid,
|
int VolumeManager::getMountModeForRunningProc(const std::vector<std::string>& packagesForUid,
|
||||||
userid_t userId, struct stat& mntWriteStat) {
|
userid_t userId, struct stat& mntWriteStat,
|
||||||
|
struct stat& mntFullStat) {
|
||||||
struct stat storageSb;
|
struct stat storageSb;
|
||||||
if (TEMP_FAILURE_RETRY(stat("/storage", &storageSb)) == -1) {
|
if (TEMP_FAILURE_RETRY(stat("/storage", &storageSb)) == -1) {
|
||||||
PLOG(ERROR) << "Failed to stat /storage";
|
PLOG(ERROR) << "Failed to stat /storage";
|
||||||
|
@ -586,9 +594,11 @@ int VolumeManager::getMountModeForRunningProc(const std::vector<std::string>& pa
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some packages have access to full external storage, identify processes belonging
|
// 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
|
// to those packages by comparing inode no.s of /mnt/runtime/full and /storage
|
||||||
if (storageSb.st_dev == mntWriteStat.st_dev && storageSb.st_ino == mntWriteStat.st_ino) {
|
if (storageSb.st_dev == mntFullStat.st_dev && storageSb.st_ino == mntFullStat.st_ino) {
|
||||||
return VoldNativeService::REMOUNT_MODE_FULL;
|
return VoldNativeService::REMOUNT_MODE_FULL;
|
||||||
|
} else if (storageSb.st_dev == mntWriteStat.st_dev && storageSb.st_ino == mntWriteStat.st_ino) {
|
||||||
|
return VoldNativeService::REMOUNT_MODE_LEGACY;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string obbMountFile =
|
std::string obbMountFile =
|
||||||
|
|
|
@ -174,7 +174,7 @@ class VolumeManager {
|
||||||
int destroySandboxForAppOnVol(const std::string& packageName, const std::string& sandboxId,
|
int destroySandboxForAppOnVol(const std::string& packageName, const std::string& sandboxId,
|
||||||
userid_t userId, const std::string& volLabel);
|
userid_t userId, const std::string& volLabel);
|
||||||
int getMountModeForRunningProc(const std::vector<std::string>& packagesForUid, userid_t userId,
|
int getMountModeForRunningProc(const std::vector<std::string>& packagesForUid, userid_t userId,
|
||||||
struct stat& mntWriteStat);
|
struct stat& mntWriteStat, struct stat& mntFullStat);
|
||||||
|
|
||||||
void handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk);
|
void handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk);
|
||||||
void handleDiskChanged(dev_t device);
|
void handleDiskChanged(dev_t device);
|
||||||
|
|
|
@ -151,8 +151,9 @@ interface IVold {
|
||||||
const int REMOUNT_MODE_DEFAULT = 1;
|
const int REMOUNT_MODE_DEFAULT = 1;
|
||||||
const int REMOUNT_MODE_READ = 2;
|
const int REMOUNT_MODE_READ = 2;
|
||||||
const int REMOUNT_MODE_WRITE = 3;
|
const int REMOUNT_MODE_WRITE = 3;
|
||||||
const int REMOUNT_MODE_INSTALLER = 4;
|
const int REMOUNT_MODE_LEGACY = 4;
|
||||||
const int REMOUNT_MODE_FULL = 5;
|
const int REMOUNT_MODE_INSTALLER = 5;
|
||||||
|
const int REMOUNT_MODE_FULL = 6;
|
||||||
|
|
||||||
const int VOLUME_STATE_UNMOUNTED = 0;
|
const int VOLUME_STATE_UNMOUNTED = 0;
|
||||||
const int VOLUME_STATE_CHECKING = 1;
|
const int VOLUME_STATE_CHECKING = 1;
|
||||||
|
|
|
@ -184,25 +184,6 @@ status_t PublicVolume::doMount() {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
PLOG(ERROR) << "Failed to exec";
|
PLOG(ERROR) << "Failed to exec";
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// In Pre-Q, apps have full read access to secondary storage devices but only
|
|
||||||
// write access for their package specific directories. In Q, they only have access
|
|
||||||
// to their own sandboxes and they can write anywhere inside the sandbox. Instead of
|
|
||||||
// updating sdcardfs to allow packages writing into their own sandboxes, we could
|
|
||||||
// just allow them to write anywhere by passing "-w".
|
|
||||||
// clang-format off
|
|
||||||
if (GetBoolProperty(kIsolatedStorage, false)) {
|
|
||||||
if (execl(kFusePath, kFusePath,
|
|
||||||
"-u", "1023", // AID_MEDIA_RW
|
|
||||||
"-g", "1023", // AID_MEDIA_RW
|
|
||||||
"-U", std::to_string(getMountUserId()).c_str(),
|
|
||||||
"-w",
|
|
||||||
mRawPath.c_str(),
|
|
||||||
stableName.c_str(),
|
|
||||||
NULL)) {
|
|
||||||
// clang-format on
|
|
||||||
PLOG(ERROR) << "Failed to exec";
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
if (execl(kFusePath, kFusePath,
|
if (execl(kFusePath, kFusePath,
|
||||||
|
@ -216,7 +197,6 @@ status_t PublicVolume::doMount() {
|
||||||
PLOG(ERROR) << "Failed to exec";
|
PLOG(ERROR) << "Failed to exec";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LOG(ERROR) << "FUSE exiting";
|
LOG(ERROR) << "FUSE exiting";
|
||||||
_exit(1);
|
_exit(1);
|
||||||
|
|
Loading…
Reference in a new issue