diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index a4c99c006d808..39038f555044e 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -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) { diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index fc2005a31696c..2c282c6a32f76 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1351,7 +1351,13 @@ static void isolateAppData(JNIEnv* env, const std::vector& 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]; @@ -1392,17 +1398,8 @@ static void isolateAppData(JNIEnv* env, const std::vector& 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, @@ -1579,10 +1576,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); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 9f2a77c05d2b6..2e628642dac59 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2214,11 +2214,11 @@ public final class ProcessList { app.setHasForegroundActivities(true); } - final Map> pkgDataInfoMap; - final Map> whitelistedAppDataInfoMap; + Map> pkgDataInfoMap; + Map> 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,