Only kill apps with storage app data isolation enabled

Originally it kills all the apps with obb and data mounted.
Due to recent changes, all apps will have obb and data dirs mounted
in default root namespace. Hence all apps will be killed by
by KillProcessesWithMounts().

To fix this, we also check if the dir is mounted as tmpfs,
as the default namespace one is bind mounted to lowerfs,
which app data isolation is mounted as tmpfs, so we only
kill the process that have obb dir mounted as tmpfs.

Bug: 148049767
Test: Able to boot without warnings / errors
Ignore-AOSP-First: Merge it along with other CLs, will cherry-pick to
AOSP afterwards.

Change-Id: I45d9a63ed47cbc27aebb63357a43f51ad62275db
This commit is contained in:
Ricky Wai 2021-04-29 17:47:28 +01:00
parent 73eda071ef
commit a58b535495
5 changed files with 14 additions and 11 deletions

View file

@ -84,7 +84,7 @@ static bool checkSymlink(const std::string& path, const std::string& prefix) {
}
// TODO: Refactor the code with KillProcessesWithOpenFiles().
int KillProcessesWithMounts(const std::string& prefix, int signal) {
int KillProcessesWithTmpfsMounts(const std::string& prefix, int signal) {
std::unordered_set<pid_t> pids;
auto proc_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
@ -112,7 +112,8 @@ int KillProcessesWithMounts(const std::string& prefix, int signal) {
// Check if obb directory is mounted, and get all packages of mounted app data directory.
mntent* mentry;
while ((mentry = getmntent(fp.get())) != nullptr) {
if (android::base::StartsWith(mentry->mnt_dir, prefix)) {
if (mentry->mnt_fsname != nullptr && strncmp(mentry->mnt_fsname, "tmpfs", 5) == 0
&& android::base::StartsWith(mentry->mnt_dir, prefix)) {
pids.insert(pid);
break;
}

View file

@ -21,7 +21,7 @@ namespace android {
namespace vold {
int KillProcessesWithOpenFiles(const std::string& path, int signal, bool killFuseDaemon = true);
int KillProcessesWithMounts(const std::string& path, int signal);
int KillProcessesWithTmpfsMounts(const std::string& path, int signal);
} // namespace vold
} // namespace android

View file

@ -499,25 +499,25 @@ status_t ForceUnmount(const std::string& path) {
return -errno;
}
status_t KillProcessesWithMountPrefix(const std::string& path) {
if (KillProcessesWithMounts(path, SIGINT) == 0) {
status_t KillProcessesWithTmpfsMountPrefix(const std::string& path) {
if (KillProcessesWithTmpfsMounts(path, SIGINT) == 0) {
return OK;
}
if (sSleepOnUnmount) sleep(5);
if (KillProcessesWithMounts(path, SIGTERM) == 0) {
if (KillProcessesWithTmpfsMounts(path, SIGTERM) == 0) {
return OK;
}
if (sSleepOnUnmount) sleep(5);
if (KillProcessesWithMounts(path, SIGKILL) == 0) {
if (KillProcessesWithTmpfsMounts(path, SIGKILL) == 0) {
return OK;
}
if (sSleepOnUnmount) sleep(5);
// Send SIGKILL a second time to determine if we've
// actually killed everyone mount
if (KillProcessesWithMounts(path, SIGKILL) == 0) {
if (KillProcessesWithTmpfsMounts(path, SIGKILL) == 0) {
return OK;
}
PLOG(ERROR) << "Failed to kill processes using " << path;

View file

@ -78,8 +78,8 @@ status_t ForceUnmount(const std::string& path);
/* Kills any processes using given path */
status_t KillProcessesUsingPath(const std::string& path);
/* Kills any processes using given mount prifix */
status_t KillProcessesWithMountPrefix(const std::string& path);
/* Kills any processes using given tmpfs mount prifix */
status_t KillProcessesWithTmpfsMountPrefix(const std::string& path);
/* Creates bind mount from source to target */
status_t BindMount(const std::string& source, const std::string& target);

View file

@ -191,7 +191,9 @@ status_t EmulatedVolume::unmountFuseBindMounts() {
// umount the whole Android/ dir.
if (mAppDataIsolationEnabled) {
std::string appObbDir(StringPrintf("%s/%d/Android/obb", getPath().c_str(), userId));
KillProcessesWithMountPrefix(appObbDir);
// Here we assume obb/data dirs is mounted as tmpfs, then it must be caused by
// app data isolation.
KillProcessesWithTmpfsMountPrefix(appObbDir);
} else {
std::string androidDataTarget(
StringPrintf("/mnt/user/%d/%s/%d/Android/data", userId, label.c_str(), userId));