Create pkg specific dirs if they are not available.
When the user clears storage for an app, it's package specific directories would be deleted, so we need to recreate them when the app is started again. Bug: 124058579 Test: manual Test: atest cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java Change-Id: I7fcf2c41d16fbcf79fc03b4c4d59baeecd6725ab
This commit is contained in:
@@ -598,23 +598,31 @@ static int UnmountTree(const char* path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void CreateDir(const std::string& dir,
|
||||
mode_t mode, uid_t uid, gid_t gid,
|
||||
fail_fn_t fail_fn) {
|
||||
if (TEMP_FAILURE_RETRY(access(dir.c_str(), F_OK)) == 0) {
|
||||
return;
|
||||
} else if (errno != ENOENT) {
|
||||
fail_fn(CREATE_ERROR("Failed to stat %s: %s", dir.c_str(), strerror(errno)));
|
||||
}
|
||||
if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
|
||||
fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s: %s",
|
||||
dir.c_str(), strerror(errno)));
|
||||
}
|
||||
}
|
||||
|
||||
static void CreatePkgSandbox(uid_t uid, const std::string& package_name, fail_fn_t fail_fn) {
|
||||
// Create /mnt/user/0/package/<package-name>
|
||||
userid_t user_id = multiuser_get_user_id(uid);
|
||||
std::string pkg_sandbox_dir = StringPrintf("/mnt/user/%d", user_id);
|
||||
if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0751, AID_ROOT, AID_ROOT) != 0) {
|
||||
fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()));
|
||||
}
|
||||
CreateDir(pkg_sandbox_dir, 0751, AID_ROOT, AID_ROOT, fail_fn);
|
||||
|
||||
StringAppendF(&pkg_sandbox_dir, "/package");
|
||||
if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
|
||||
fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()));
|
||||
}
|
||||
CreateDir(pkg_sandbox_dir, 0700, AID_ROOT, AID_ROOT, fail_fn);
|
||||
|
||||
StringAppendF(&pkg_sandbox_dir, "/%s", package_name.c_str());
|
||||
if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0755, uid, uid) != 0) {
|
||||
fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str()));
|
||||
}
|
||||
CreateDir(pkg_sandbox_dir, 0700, AID_ROOT, AID_ROOT, fail_fn);
|
||||
}
|
||||
|
||||
static void BindMount(const std::string& sourceDir, const std::string& targetDir,
|
||||
@@ -629,20 +637,41 @@ static void BindMount(const std::string& sourceDir, const std::string& targetDir
|
||||
static void MountPkgSpecificDir(const std::string& mntSourceRoot,
|
||||
const std::string& mntTargetRoot,
|
||||
const std::string& packageName,
|
||||
uid_t uid,
|
||||
const char* dirName,
|
||||
fail_fn_t fail_fn) {
|
||||
std::string mntSourceDir = StringPrintf("%s/Android/%s/%s",
|
||||
mntSourceRoot.c_str(), dirName, packageName.c_str());
|
||||
CreateDir(mntSourceDir, 0755, uid, uid, fail_fn);
|
||||
|
||||
std::string mntTargetDir = StringPrintf("%s/Android/%s/%s",
|
||||
mntTargetRoot.c_str(), dirName, packageName.c_str());
|
||||
CreateDir(mntTargetDir, 0755, uid, uid, fail_fn);
|
||||
|
||||
BindMount(mntSourceDir, mntTargetDir, fail_fn);
|
||||
}
|
||||
|
||||
|
||||
static void createPkgSpecificDirRoots(const std::string& parentDir,
|
||||
bool createSandbox,
|
||||
mode_t mode, uid_t uid, gid_t gid,
|
||||
fail_fn_t fail_fn) {
|
||||
std::string androidDir = StringPrintf("%s/Android", parentDir.c_str());
|
||||
CreateDir(androidDir, mode, uid, gid, fail_fn);
|
||||
std::vector<std::string> dirs = {"data", "media", "obb"};
|
||||
if (createSandbox) {
|
||||
dirs.push_back("sandbox");
|
||||
}
|
||||
for (auto& dir : dirs) {
|
||||
std::string path = StringPrintf("%s/%s", androidDir.c_str(), dir.c_str());
|
||||
CreateDir(path, mode, uid, gid, fail_fn);
|
||||
}
|
||||
}
|
||||
|
||||
static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames,
|
||||
const std::vector<std::string>& volumeLabels,
|
||||
bool mountAllObbs, const std::string& sandboxId,
|
||||
userid_t userId, fail_fn_t fail_fn) {
|
||||
userid_t userId, uid_t uid, fail_fn_t fail_fn) {
|
||||
for (auto& label : volumeLabels) {
|
||||
std::string mntSource = StringPrintf("/mnt/runtime/write/%s", label.c_str());
|
||||
std::string mntTarget = StringPrintf("/storage/%s", label.c_str());
|
||||
@@ -651,15 +680,26 @@ static void PreparePkgSpecificDirs(const std::vector<std::string>& packageNames,
|
||||
StringAppendF(&mntTarget, "/%d", userId);
|
||||
}
|
||||
|
||||
if (TEMP_FAILURE_RETRY(access(mntSource.c_str(), F_OK)) < 0) {
|
||||
ALOGE("Can't access %s: %s", mntSource.c_str(), strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create /mnt/runtime/write/emulated/0/Android/{data,media,obb,sandbox}
|
||||
createPkgSpecificDirRoots(mntSource, true, 0700, AID_ROOT, AID_ROOT, fail_fn);
|
||||
|
||||
std::string sandboxSource = StringPrintf("%s/Android/sandbox/%s",
|
||||
mntSource.c_str(), sandboxId.c_str());
|
||||
CreateDir(sandboxSource, 0755, uid, uid, fail_fn);
|
||||
BindMount(sandboxSource, mntTarget, fail_fn);
|
||||
|
||||
// Create /storage/emulated/0/Android/{data,media,obb}
|
||||
createPkgSpecificDirRoots(mntTarget, false, 0755, uid, uid, fail_fn);
|
||||
for (auto& package : packageNames) {
|
||||
MountPkgSpecificDir(mntSource, mntTarget, package, "data", fail_fn);
|
||||
MountPkgSpecificDir(mntSource, mntTarget, package, "media", fail_fn);
|
||||
MountPkgSpecificDir(mntSource, mntTarget, package, uid, "data", fail_fn);
|
||||
MountPkgSpecificDir(mntSource, mntTarget, package, uid, "media", fail_fn);
|
||||
if (!mountAllObbs) {
|
||||
MountPkgSpecificDir(mntSource, mntTarget, package, "obb", fail_fn);
|
||||
MountPkgSpecificDir(mntSource, mntTarget, package, uid, "obb", fail_fn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -774,7 +814,7 @@ static void MountEmulatedStorage(uid_t uid, jint mount_mode,
|
||||
// care of by vold later.
|
||||
if (sandboxAlreadyCreated) {
|
||||
PreparePkgSpecificDirs(packages_for_uid, visible_vol_ids,
|
||||
mount_mode == MOUNT_EXTERNAL_INSTALLER, sandbox_id, user_id, fail_fn);
|
||||
mount_mode == MOUNT_EXTERNAL_INSTALLER, sandbox_id, user_id, uid, fail_fn);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user