Merge "Apply app data isolation on isolated or app zygote processes" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8434b9fc88
@@ -1318,15 +1318,15 @@ public class ZygoteProcess {
|
||||
|
||||
Process.ProcessStartResult result;
|
||||
try {
|
||||
// As app zygote is for generating isolated process, at the end it can't access
|
||||
// apps data, so doesn't need to its data info.
|
||||
// We will bind mount app data dirs so app zygote can't access /data/data, while
|
||||
// we don't need to bind mount storage dirs as /storage won't be mounted.
|
||||
result = startViaZygote(processClass, niceName, uid, gid,
|
||||
gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
|
||||
abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
|
||||
true /* startChildZygote */, null /* packageName */,
|
||||
ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS /* zygotePolicyFlags */, false /* isTopApp */,
|
||||
null /* disabledCompatChanges */, null /* pkgDataInfoMap */,
|
||||
null /* whitelistedDataInfoMap */, false /* bindMountAppsData*/,
|
||||
null /* whitelistedDataInfoMap */, true /* bindMountAppsData*/,
|
||||
/* bindMountAppStorageDirs */ false, extraArgs);
|
||||
|
||||
} catch (ZygoteStartFailedEx ex) {
|
||||
|
||||
@@ -1359,7 +1359,13 @@ static void isolateAppData(JNIEnv* env, const std::vector<std::string>& merged_d
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
bool legacySymlinkCreated = false;
|
||||
// Prepare default dirs for user 0 as user 0 always exists.
|
||||
int result = symlink("/data/data", "/data/user/0");
|
||||
if (result != 0) {
|
||||
fail_fn(CREATE_ERROR("Failed to create symlink /data/user/0 %s", strerror(errno)));
|
||||
}
|
||||
PrepareDirIfNotPresent("/data/user_de/0", DEFAULT_DATA_DIR_PERMISSION,
|
||||
AID_ROOT, AID_ROOT, fail_fn);
|
||||
|
||||
for (int i = 0; i < size; i += 3) {
|
||||
std::string const & packageName = merged_data_info_list[i];
|
||||
@@ -1400,17 +1406,8 @@ static void isolateAppData(JNIEnv* env, const std::vector<std::string>& merged_d
|
||||
char internalDeUserPath[PATH_MAX];
|
||||
snprintf(internalCeUserPath, PATH_MAX, "/data/user/%d", userId);
|
||||
snprintf(internalDeUserPath, PATH_MAX, "/data/user_de/%d", userId);
|
||||
// If it's user 0, create a symlink /data/user/0 -> /data/data,
|
||||
// otherwise create /data/user/$USER
|
||||
// If it's not user 0, create /data/user/$USER.
|
||||
if (userId == 0) {
|
||||
if (!legacySymlinkCreated) {
|
||||
legacySymlinkCreated = true;
|
||||
int result = symlink(internalLegacyCePath, internalCeUserPath);
|
||||
if (result != 0) {
|
||||
fail_fn(CREATE_ERROR("Failed to create symlink %s %s", internalCeUserPath,
|
||||
strerror(errno)));
|
||||
}
|
||||
}
|
||||
actualCePath = internalLegacyCePath;
|
||||
} else {
|
||||
PrepareDirIfNotPresent(internalCeUserPath, DEFAULT_DATA_DIR_PERMISSION,
|
||||
@@ -1587,10 +1584,6 @@ static void BindMountStorageDirs(JNIEnv* env, jobjectArray pkg_data_info_list,
|
||||
// Fuse is ready, so we can start using fuse path.
|
||||
int size = (pkg_data_info_list != nullptr) ? env->GetArrayLength(pkg_data_info_list) : 0;
|
||||
|
||||
if (size == 0) {
|
||||
fail_fn(CREATE_ERROR("Data package list cannot be empty"));
|
||||
}
|
||||
|
||||
// Create tmpfs on Android/obb and Android/data so these 2 dirs won't enter fuse anymore.
|
||||
std::string androidObbDir = StringPrintf("/storage/emulated/%d/Android/obb", user_id);
|
||||
MountAppDataTmpFs(androidObbDir, fail_fn);
|
||||
|
||||
@@ -2214,11 +2214,11 @@ public final class ProcessList {
|
||||
app.setHasForegroundActivities(true);
|
||||
}
|
||||
|
||||
final Map<String, Pair<String, Long>> pkgDataInfoMap;
|
||||
final Map<String, Pair<String, Long>> whitelistedAppDataInfoMap;
|
||||
Map<String, Pair<String, Long>> pkgDataInfoMap;
|
||||
Map<String, Pair<String, Long>> whitelistedAppDataInfoMap;
|
||||
boolean bindMountAppStorageDirs = false;
|
||||
boolean bindMountAppsData = mAppDataIsolationEnabled
|
||||
&& UserHandle.isApp(app.uid)
|
||||
&& (UserHandle.isApp(app.uid) || UserHandle.isIsolated(app.uid))
|
||||
&& mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info);
|
||||
|
||||
// Get all packages belongs to the same shared uid. sharedPackages is empty array
|
||||
@@ -2266,6 +2266,13 @@ public final class ProcessList {
|
||||
}
|
||||
}
|
||||
|
||||
// If it's an isolated process, it should not even mount its own app data directories,
|
||||
// since it has no access to them anyway.
|
||||
if (app.isolated) {
|
||||
pkgDataInfoMap = null;
|
||||
whitelistedAppDataInfoMap = null;
|
||||
}
|
||||
|
||||
final Process.ProcessStartResult startResult;
|
||||
if (hostingRecord.usesWebviewZygote()) {
|
||||
startResult = startWebView(entryPoint,
|
||||
@@ -2276,13 +2283,14 @@ public final class ProcessList {
|
||||
} else if (hostingRecord.usesAppZygote()) {
|
||||
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
|
||||
|
||||
// We can't isolate app data and storage data as parent zygote already did that.
|
||||
startResult = appZygote.getProcess().start(entryPoint,
|
||||
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
|
||||
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
|
||||
app.info.dataDir, null, app.info.packageName,
|
||||
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
|
||||
app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
|
||||
bindMountAppsData, bindMountAppStorageDirs,
|
||||
false, false,
|
||||
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
|
||||
} else {
|
||||
startResult = Process.start(entryPoint,
|
||||
|
||||
Reference in New Issue
Block a user