Merge "Revert "Revert "Do not mount whitelisted package in storage data and obb dirs""" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
afef06a0f6
@@ -607,6 +607,9 @@ public class Process {
|
|||||||
* started.
|
* started.
|
||||||
* @param pkgDataInfoMap Map from related package names to private data directory
|
* @param pkgDataInfoMap Map from related package names to private data directory
|
||||||
* volume UUID and inode number.
|
* volume UUID and inode number.
|
||||||
|
* @param whitelistedDataInfoMap Map from whitelisted package names to private data directory
|
||||||
|
* volume UUID and inode number.
|
||||||
|
* @param bindMountAppsData whether zygote needs to mount CE and DE data.
|
||||||
* @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
|
* @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
|
||||||
* @param zygoteArgs Additional arguments to supply to the zygote process.
|
* @param zygoteArgs Additional arguments to supply to the zygote process.
|
||||||
* @return An object that describes the result of the attempt to start the process.
|
* @return An object that describes the result of the attempt to start the process.
|
||||||
@@ -631,13 +634,17 @@ public class Process {
|
|||||||
@Nullable long[] disabledCompatChanges,
|
@Nullable long[] disabledCompatChanges,
|
||||||
@Nullable Map<String, Pair<String, Long>>
|
@Nullable Map<String, Pair<String, Long>>
|
||||||
pkgDataInfoMap,
|
pkgDataInfoMap,
|
||||||
|
@Nullable Map<String, Pair<String, Long>>
|
||||||
|
whitelistedDataInfoMap,
|
||||||
|
boolean bindMountAppsData,
|
||||||
boolean bindMountAppStorageDirs,
|
boolean bindMountAppStorageDirs,
|
||||||
@Nullable String[] zygoteArgs) {
|
@Nullable String[] zygoteArgs) {
|
||||||
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
|
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
|
||||||
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
||||||
abi, instructionSet, appDataDir, invokeWith, packageName,
|
abi, instructionSet, appDataDir, invokeWith, packageName,
|
||||||
zygotePolicyFlags, isTopApp, disabledCompatChanges,
|
zygotePolicyFlags, isTopApp, disabledCompatChanges,
|
||||||
pkgDataInfoMap, bindMountAppStorageDirs, zygoteArgs);
|
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
|
||||||
|
bindMountAppStorageDirs, zygoteArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@@ -661,7 +668,8 @@ public class Process {
|
|||||||
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
||||||
abi, instructionSet, appDataDir, invokeWith, packageName,
|
abi, instructionSet, appDataDir, invokeWith, packageName,
|
||||||
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, /*isTopApp=*/ false,
|
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, /*isTopApp=*/ false,
|
||||||
disabledCompatChanges, /* pkgDataInfoMap */ null, false, zygoteArgs);
|
disabledCompatChanges, /* pkgDataInfoMap */ null,
|
||||||
|
/* whitelistedDataInfoMap */ null, false, false, zygoteArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -333,6 +333,9 @@ public class ZygoteProcess {
|
|||||||
* started.
|
* started.
|
||||||
* @param pkgDataInfoMap Map from related package names to private data directory
|
* @param pkgDataInfoMap Map from related package names to private data directory
|
||||||
* volume UUID and inode number.
|
* volume UUID and inode number.
|
||||||
|
* @param whitelistedDataInfoMap Map from whitelisted package names to private data directory
|
||||||
|
* volume UUID and inode number.
|
||||||
|
* @param bindMountAppsData whether zygote needs to mount CE and DE data.
|
||||||
* @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
|
* @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
|
||||||
*
|
*
|
||||||
* @param zygoteArgs Additional arguments to supply to the Zygote process.
|
* @param zygoteArgs Additional arguments to supply to the Zygote process.
|
||||||
@@ -355,6 +358,9 @@ public class ZygoteProcess {
|
|||||||
@Nullable long[] disabledCompatChanges,
|
@Nullable long[] disabledCompatChanges,
|
||||||
@Nullable Map<String, Pair<String, Long>>
|
@Nullable Map<String, Pair<String, Long>>
|
||||||
pkgDataInfoMap,
|
pkgDataInfoMap,
|
||||||
|
@Nullable Map<String, Pair<String, Long>>
|
||||||
|
whitelistedDataInfoMap,
|
||||||
|
boolean bindMountAppsData,
|
||||||
boolean bindMountAppStorageDirs,
|
boolean bindMountAppStorageDirs,
|
||||||
@Nullable String[] zygoteArgs) {
|
@Nullable String[] zygoteArgs) {
|
||||||
// TODO (chriswailes): Is there a better place to check this value?
|
// TODO (chriswailes): Is there a better place to check this value?
|
||||||
@@ -367,7 +373,8 @@ public class ZygoteProcess {
|
|||||||
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
||||||
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
|
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
|
||||||
packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
|
packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
|
||||||
pkgDataInfoMap, bindMountAppStorageDirs, zygoteArgs);
|
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
|
||||||
|
bindMountAppStorageDirs, zygoteArgs);
|
||||||
} catch (ZygoteStartFailedEx ex) {
|
} catch (ZygoteStartFailedEx ex) {
|
||||||
Log.e(LOG_TAG,
|
Log.e(LOG_TAG,
|
||||||
"Starting VM process through Zygote failed");
|
"Starting VM process through Zygote failed");
|
||||||
@@ -608,6 +615,9 @@ public class ZygoteProcess {
|
|||||||
* @param disabledCompatChanges a list of disabled compat changes for the process being started.
|
* @param disabledCompatChanges a list of disabled compat changes for the process being started.
|
||||||
* @param pkgDataInfoMap Map from related package names to private data directory volume UUID
|
* @param pkgDataInfoMap Map from related package names to private data directory volume UUID
|
||||||
* and inode number.
|
* and inode number.
|
||||||
|
* @param whitelistedDataInfoMap Map from whitelisted package names to private data directory
|
||||||
|
* volume UUID and inode number.
|
||||||
|
* @param bindMountAppsData whether zygote needs to mount CE and DE data.
|
||||||
* @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
|
* @param bindMountAppStorageDirs whether zygote needs to mount Android/obb and Android/data.
|
||||||
* @param extraArgs Additional arguments to supply to the zygote process.
|
* @param extraArgs Additional arguments to supply to the zygote process.
|
||||||
* @return An object that describes the result of the attempt to start the process.
|
* @return An object that describes the result of the attempt to start the process.
|
||||||
@@ -631,6 +641,9 @@ public class ZygoteProcess {
|
|||||||
@Nullable long[] disabledCompatChanges,
|
@Nullable long[] disabledCompatChanges,
|
||||||
@Nullable Map<String, Pair<String, Long>>
|
@Nullable Map<String, Pair<String, Long>>
|
||||||
pkgDataInfoMap,
|
pkgDataInfoMap,
|
||||||
|
@Nullable Map<String, Pair<String, Long>>
|
||||||
|
whitelistedDataInfoMap,
|
||||||
|
boolean bindMountAppsData,
|
||||||
boolean bindMountAppStorageDirs,
|
boolean bindMountAppStorageDirs,
|
||||||
@Nullable String[] extraArgs)
|
@Nullable String[] extraArgs)
|
||||||
throws ZygoteStartFailedEx {
|
throws ZygoteStartFailedEx {
|
||||||
@@ -728,11 +741,33 @@ public class ZygoteProcess {
|
|||||||
}
|
}
|
||||||
argsForZygote.add(sb.toString());
|
argsForZygote.add(sb.toString());
|
||||||
}
|
}
|
||||||
|
if (whitelistedDataInfoMap != null && whitelistedDataInfoMap.size() > 0) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(Zygote.WHITELISTED_DATA_INFO_MAP);
|
||||||
|
sb.append("=");
|
||||||
|
boolean started = false;
|
||||||
|
for (Map.Entry<String, Pair<String, Long>> entry : whitelistedDataInfoMap.entrySet()) {
|
||||||
|
if (started) {
|
||||||
|
sb.append(',');
|
||||||
|
}
|
||||||
|
started = true;
|
||||||
|
sb.append(entry.getKey());
|
||||||
|
sb.append(',');
|
||||||
|
sb.append(entry.getValue().first);
|
||||||
|
sb.append(',');
|
||||||
|
sb.append(entry.getValue().second);
|
||||||
|
}
|
||||||
|
argsForZygote.add(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
if (bindMountAppStorageDirs) {
|
if (bindMountAppStorageDirs) {
|
||||||
argsForZygote.add(Zygote.BIND_MOUNT_APP_STORAGE_DIRS);
|
argsForZygote.add(Zygote.BIND_MOUNT_APP_STORAGE_DIRS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bindMountAppsData) {
|
||||||
|
argsForZygote.add(Zygote.BIND_MOUNT_APP_DATA_DIRS);
|
||||||
|
}
|
||||||
|
|
||||||
if (disabledCompatChanges != null && disabledCompatChanges.length > 0) {
|
if (disabledCompatChanges != null && disabledCompatChanges.length > 0) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("--disabled-compat-changes=");
|
sb.append("--disabled-compat-changes=");
|
||||||
@@ -1291,6 +1326,7 @@ public class ZygoteProcess {
|
|||||||
true /* startChildZygote */, null /* packageName */,
|
true /* startChildZygote */, null /* packageName */,
|
||||||
ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS /* zygotePolicyFlags */, false /* isTopApp */,
|
ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS /* zygotePolicyFlags */, false /* isTopApp */,
|
||||||
null /* disabledCompatChanges */, null /* pkgDataInfoMap */,
|
null /* disabledCompatChanges */, null /* pkgDataInfoMap */,
|
||||||
|
null /* whitelistedDataInfoMap */, false /* bindMountAppsData*/,
|
||||||
/* bindMountAppStorageDirs */ false, extraArgs);
|
/* bindMountAppStorageDirs */ false, extraArgs);
|
||||||
|
|
||||||
} catch (ZygoteStartFailedEx ex) {
|
} catch (ZygoteStartFailedEx ex) {
|
||||||
|
|||||||
@@ -205,9 +205,15 @@ public final class Zygote {
|
|||||||
/** List of packages with the same uid, and its app data info: volume uuid and inode. */
|
/** List of packages with the same uid, and its app data info: volume uuid and inode. */
|
||||||
public static final String PKG_DATA_INFO_MAP = "--pkg-data-info-map";
|
public static final String PKG_DATA_INFO_MAP = "--pkg-data-info-map";
|
||||||
|
|
||||||
|
/** List of whitelisted packages and its app data info: volume uuid and inode. */
|
||||||
|
public static final String WHITELISTED_DATA_INFO_MAP = "--whitelisted-data-info-map";
|
||||||
|
|
||||||
/** Bind mount app storage dirs to lower fs not via fuse */
|
/** Bind mount app storage dirs to lower fs not via fuse */
|
||||||
public static final String BIND_MOUNT_APP_STORAGE_DIRS = "--bind-mount-storage-dirs";
|
public static final String BIND_MOUNT_APP_STORAGE_DIRS = "--bind-mount-storage-dirs";
|
||||||
|
|
||||||
|
/** Bind mount app storage dirs to lower fs not via fuse */
|
||||||
|
public static final String BIND_MOUNT_APP_DATA_DIRS = "--bind-mount-data-dirs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An extraArg passed when a zygote process is forking a child-zygote, specifying a name
|
* An extraArg passed when a zygote process is forking a child-zygote, specifying a name
|
||||||
* in the abstract socket namespace. This socket name is what the new child zygote
|
* in the abstract socket namespace. This socket name is what the new child zygote
|
||||||
@@ -313,6 +319,8 @@ public final class Zygote {
|
|||||||
* @param isTopApp true if the process is for top (high priority) application.
|
* @param isTopApp true if the process is for top (high priority) application.
|
||||||
* @param pkgDataInfoList A list that stores related packages and its app data
|
* @param pkgDataInfoList A list that stores related packages and its app data
|
||||||
* info: volume uuid and inode.
|
* info: volume uuid and inode.
|
||||||
|
* @param whitelistedDataInfoList Like pkgDataInfoList, but it's for whitelisted apps.
|
||||||
|
* @param bindMountAppDataDirs True if the zygote needs to mount data dirs.
|
||||||
* @param bindMountAppStorageDirs True if the zygote needs to mount storage dirs.
|
* @param bindMountAppStorageDirs True if the zygote needs to mount storage dirs.
|
||||||
*
|
*
|
||||||
* @return 0 if this is the child, pid of the child
|
* @return 0 if this is the child, pid of the child
|
||||||
@@ -321,13 +329,15 @@ public final class Zygote {
|
|||||||
static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
|
static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
|
||||||
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
|
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
|
||||||
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
|
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
|
||||||
boolean isTopApp, String[] pkgDataInfoList, boolean bindMountAppStorageDirs) {
|
boolean isTopApp, String[] pkgDataInfoList, String[] whitelistedDataInfoList,
|
||||||
|
boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
|
||||||
ZygoteHooks.preFork();
|
ZygoteHooks.preFork();
|
||||||
|
|
||||||
int pid = nativeForkAndSpecialize(
|
int pid = nativeForkAndSpecialize(
|
||||||
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
|
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
|
||||||
fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
|
fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
|
||||||
pkgDataInfoList, bindMountAppStorageDirs);
|
pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,
|
||||||
|
bindMountAppStorageDirs);
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
// Note that this event ends at the end of handleChildProc,
|
// Note that this event ends at the end of handleChildProc,
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
|
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
|
||||||
@@ -344,6 +354,7 @@ public final class Zygote {
|
|||||||
int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
|
int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
|
||||||
int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
|
int[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
|
||||||
String appDataDir, boolean isTopApp, String[] pkgDataInfoList,
|
String appDataDir, boolean isTopApp, String[] pkgDataInfoList,
|
||||||
|
String[] whitelistedDataInfoList, boolean bindMountAppDataDirs,
|
||||||
boolean bindMountAppStorageDirs);
|
boolean bindMountAppStorageDirs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -371,15 +382,19 @@ public final class Zygote {
|
|||||||
* volume uuid and CE dir inode. For example, pkgDataInfoList = [app_a_pkg_name,
|
* volume uuid and CE dir inode. For example, pkgDataInfoList = [app_a_pkg_name,
|
||||||
* app_a_data_volume_uuid, app_a_ce_inode, app_b_pkg_name, app_b_data_volume_uuid,
|
* app_a_data_volume_uuid, app_a_ce_inode, app_b_pkg_name, app_b_data_volume_uuid,
|
||||||
* app_b_ce_inode, ...];
|
* app_b_ce_inode, ...];
|
||||||
|
* @param whitelistedDataInfoList Like pkgDataInfoList, but it's for whitelisted apps.
|
||||||
|
* @param bindMountAppDataDirs True if the zygote needs to mount data dirs.
|
||||||
* @param bindMountAppStorageDirs True if the zygote needs to mount storage dirs.
|
* @param bindMountAppStorageDirs True if the zygote needs to mount storage dirs.
|
||||||
*/
|
*/
|
||||||
private static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,
|
private static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,
|
||||||
int[][] rlimits, int mountExternal, String seInfo, String niceName,
|
int[][] rlimits, int mountExternal, String seInfo, String niceName,
|
||||||
boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp,
|
boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp,
|
||||||
String[] pkgDataInfoList, boolean bindMountAppStorageDirs) {
|
String[] pkgDataInfoList, String[] whitelistedDataInfoList,
|
||||||
|
boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
|
||||||
nativeSpecializeAppProcess(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
|
nativeSpecializeAppProcess(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
|
||||||
niceName, startChildZygote, instructionSet, appDataDir, isTopApp,
|
niceName, startChildZygote, instructionSet, appDataDir, isTopApp,
|
||||||
pkgDataInfoList, bindMountAppStorageDirs);
|
pkgDataInfoList, whitelistedDataInfoList,
|
||||||
|
bindMountAppDataDirs, bindMountAppStorageDirs);
|
||||||
|
|
||||||
// Note that this event ends at the end of handleChildProc.
|
// Note that this event ends at the end of handleChildProc.
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
|
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
|
||||||
@@ -399,7 +414,8 @@ public final class Zygote {
|
|||||||
private static native void nativeSpecializeAppProcess(int uid, int gid, int[] gids,
|
private static native void nativeSpecializeAppProcess(int uid, int gid, int[] gids,
|
||||||
int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
|
int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
|
||||||
boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp,
|
boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp,
|
||||||
String[] pkgDataInfoList, boolean bindMountAppStorageDirs);
|
String[] pkgDataInfoList, String[] whitelistedDataInfoList,
|
||||||
|
boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to do any initialization before starting an application.
|
* Called to do any initialization before starting an application.
|
||||||
@@ -724,7 +740,8 @@ public final class Zygote {
|
|||||||
args.mRuntimeFlags, rlimits, args.mMountExternal,
|
args.mRuntimeFlags, rlimits, args.mMountExternal,
|
||||||
args.mSeInfo, args.mNiceName, args.mStartChildZygote,
|
args.mSeInfo, args.mNiceName, args.mStartChildZygote,
|
||||||
args.mInstructionSet, args.mAppDataDir, args.mIsTopApp,
|
args.mInstructionSet, args.mAppDataDir, args.mIsTopApp,
|
||||||
args.mPkgDataInfoList, args.mBindMountAppStorageDirs);
|
args.mPkgDataInfoList, args.mWhitelistedDataInfoList,
|
||||||
|
args.mBindMountAppDataDirs, args.mBindMountAppStorageDirs);
|
||||||
|
|
||||||
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
|
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
|
||||||
|
|
||||||
|
|||||||
@@ -226,11 +226,22 @@ class ZygoteArguments {
|
|||||||
*/
|
*/
|
||||||
String[] mPkgDataInfoList;
|
String[] mPkgDataInfoList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list that stores all whitelisted app data info: volume uuid and inode.
|
||||||
|
* Null if it does need to do app data isolation.
|
||||||
|
*/
|
||||||
|
String[] mWhitelistedDataInfoList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Zygote#BIND_MOUNT_APP_STORAGE_DIRS
|
* @see Zygote#BIND_MOUNT_APP_STORAGE_DIRS
|
||||||
*/
|
*/
|
||||||
boolean mBindMountAppStorageDirs;
|
boolean mBindMountAppStorageDirs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Zygote#BIND_MOUNT_APP_DATA_DIRS
|
||||||
|
*/
|
||||||
|
boolean mBindMountAppDataDirs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs instance and parses args
|
* Constructs instance and parses args
|
||||||
*
|
*
|
||||||
@@ -452,8 +463,12 @@ class ZygoteArguments {
|
|||||||
}
|
}
|
||||||
} else if (arg.startsWith(Zygote.PKG_DATA_INFO_MAP)) {
|
} else if (arg.startsWith(Zygote.PKG_DATA_INFO_MAP)) {
|
||||||
mPkgDataInfoList = getAssignmentList(arg);
|
mPkgDataInfoList = getAssignmentList(arg);
|
||||||
|
} else if (arg.startsWith(Zygote.WHITELISTED_DATA_INFO_MAP)) {
|
||||||
|
mWhitelistedDataInfoList = getAssignmentList(arg);
|
||||||
} else if (arg.equals(Zygote.BIND_MOUNT_APP_STORAGE_DIRS)) {
|
} else if (arg.equals(Zygote.BIND_MOUNT_APP_STORAGE_DIRS)) {
|
||||||
mBindMountAppStorageDirs = true;
|
mBindMountAppStorageDirs = true;
|
||||||
|
} else if (arg.equals(Zygote.BIND_MOUNT_APP_DATA_DIRS)) {
|
||||||
|
mBindMountAppDataDirs = true;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,7 +258,8 @@ class ZygoteConnection {
|
|||||||
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
|
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
|
||||||
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
|
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
|
||||||
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
|
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
|
||||||
parsedArgs.mPkgDataInfoList, parsedArgs.mBindMountAppStorageDirs);
|
parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
|
||||||
|
parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ using android::base::StringAppendF;
|
|||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
using android::base::WriteStringToFile;
|
using android::base::WriteStringToFile;
|
||||||
using android::base::GetBoolProperty;
|
using android::base::GetBoolProperty;
|
||||||
using android::base::GetProperty;
|
|
||||||
|
|
||||||
#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \
|
#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \
|
||||||
append(StringPrintf(__VA_ARGS__))
|
append(StringPrintf(__VA_ARGS__))
|
||||||
@@ -170,18 +169,6 @@ static int gSystemServerSocketFd = -1;
|
|||||||
|
|
||||||
static constexpr int DEFAULT_DATA_DIR_PERMISSION = 0751;
|
static constexpr int DEFAULT_DATA_DIR_PERMISSION = 0751;
|
||||||
|
|
||||||
/**
|
|
||||||
* Property to control if app data isolation is enabled.
|
|
||||||
*/
|
|
||||||
static const std::string ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY =
|
|
||||||
"persist.zygote.app_data_isolation";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Property to enable app data isolation for sdcard obb or data in vold.
|
|
||||||
*/
|
|
||||||
static const std::string ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
|
|
||||||
"persist.sys.vold_app_data_isolation_enabled";
|
|
||||||
|
|
||||||
static constexpr const uint64_t UPPER_HALF_WORD_MASK = 0xFFFF'FFFF'0000'0000;
|
static constexpr const uint64_t UPPER_HALF_WORD_MASK = 0xFFFF'FFFF'0000'0000;
|
||||||
static constexpr const uint64_t LOWER_HALF_WORD_MASK = 0x0000'0000'FFFF'FFFF;
|
static constexpr const uint64_t LOWER_HALF_WORD_MASK = 0x0000'0000'FFFF'FFFF;
|
||||||
|
|
||||||
@@ -1319,20 +1306,13 @@ static void relabelAllDirs(const char* path, security_context_t context, fail_fn
|
|||||||
* be decrypted after storage is decrypted.
|
* be decrypted after storage is decrypted.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void isolateAppData(JNIEnv* env, jobjectArray pkg_data_info_list,
|
static void isolateAppData(JNIEnv* env, const std::vector<std::string>& merged_data_info_list,
|
||||||
uid_t uid, const char* process_name, jstring managed_nice_name,
|
uid_t uid, const char* process_name,
|
||||||
fail_fn_t fail_fn) {
|
jstring managed_nice_name, fail_fn_t fail_fn) {
|
||||||
|
|
||||||
const userid_t userId = multiuser_get_user_id(uid);
|
const userid_t userId = multiuser_get_user_id(uid);
|
||||||
|
|
||||||
auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
|
int size = merged_data_info_list.size();
|
||||||
|
|
||||||
int size = (pkg_data_info_list != nullptr) ? env->GetArrayLength(pkg_data_info_list) : 0;
|
|
||||||
// Size should be a multiple of 3, as it contains list of <package_name, volume_uuid, inode>
|
|
||||||
if ((size % 3) != 0) {
|
|
||||||
fail_fn(CREATE_ERROR("Wrong pkg_inode_list size %d", size));
|
|
||||||
}
|
|
||||||
ensureInAppMountNamespace(fail_fn);
|
|
||||||
|
|
||||||
// Mount tmpfs on all possible data directories, so app no longer see the original apps data.
|
// Mount tmpfs on all possible data directories, so app no longer see the original apps data.
|
||||||
char internalCePath[PATH_MAX];
|
char internalCePath[PATH_MAX];
|
||||||
@@ -1377,14 +1357,10 @@ static void isolateAppData(JNIEnv* env, jobjectArray pkg_data_info_list,
|
|||||||
bool legacySymlinkCreated = false;
|
bool legacySymlinkCreated = false;
|
||||||
|
|
||||||
for (int i = 0; i < size; i += 3) {
|
for (int i = 0; i < size; i += 3) {
|
||||||
jstring package_str = (jstring) (env->GetObjectArrayElement(pkg_data_info_list, i));
|
std::string const & packageName = merged_data_info_list[i];
|
||||||
std::string packageName = extract_fn(package_str).value();
|
std::string const & volUuid = merged_data_info_list[i + 1];
|
||||||
|
std::string const & inode = merged_data_info_list[i + 2];
|
||||||
|
|
||||||
jstring vol_str = (jstring) (env->GetObjectArrayElement(pkg_data_info_list, i + 1));
|
|
||||||
std::string volUuid = extract_fn(vol_str).value();
|
|
||||||
|
|
||||||
jstring inode_str = (jstring) (env->GetObjectArrayElement(pkg_data_info_list, i + 2));
|
|
||||||
std::string inode = extract_fn(inode_str).value();
|
|
||||||
std::string::size_type sz;
|
std::string::size_type sz;
|
||||||
long long ceDataInode = std::stoll(inode, &sz);
|
long long ceDataInode = std::stoll(inode, &sz);
|
||||||
|
|
||||||
@@ -1482,6 +1458,48 @@ static void isolateAppData(JNIEnv* env, jobjectArray pkg_data_info_list,
|
|||||||
freecon(dataDataContext);
|
freecon(dataDataContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void insertPackagesToMergedList(JNIEnv* env,
|
||||||
|
std::vector<std::string>& merged_data_info_list,
|
||||||
|
jobjectArray data_info_list, const char* process_name,
|
||||||
|
jstring managed_nice_name, fail_fn_t fail_fn) {
|
||||||
|
|
||||||
|
auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
|
||||||
|
|
||||||
|
int size = (data_info_list != nullptr) ? env->GetArrayLength(data_info_list) : 0;
|
||||||
|
// Size should be a multiple of 3, as it contains list of <package_name, volume_uuid, inode>
|
||||||
|
if ((size % 3) != 0) {
|
||||||
|
fail_fn(CREATE_ERROR("Wrong data_info_list size %d", size));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i += 3) {
|
||||||
|
jstring package_str = (jstring) (env->GetObjectArrayElement(data_info_list, i));
|
||||||
|
std::string packageName = extract_fn(package_str).value();
|
||||||
|
merged_data_info_list.push_back(packageName);
|
||||||
|
|
||||||
|
jstring vol_str = (jstring) (env->GetObjectArrayElement(data_info_list, i + 1));
|
||||||
|
std::string volUuid = extract_fn(vol_str).value();
|
||||||
|
merged_data_info_list.push_back(volUuid);
|
||||||
|
|
||||||
|
jstring inode_str = (jstring) (env->GetObjectArrayElement(data_info_list, i + 2));
|
||||||
|
std::string inode = extract_fn(inode_str).value();
|
||||||
|
merged_data_info_list.push_back(inode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void isolateAppData(JNIEnv* env, jobjectArray pkg_data_info_list,
|
||||||
|
jobjectArray whitelisted_data_info_list, uid_t uid, const char* process_name,
|
||||||
|
jstring managed_nice_name, fail_fn_t fail_fn) {
|
||||||
|
|
||||||
|
ensureInAppMountNamespace(fail_fn);
|
||||||
|
std::vector<std::string> merged_data_info_list;
|
||||||
|
insertPackagesToMergedList(env, merged_data_info_list, pkg_data_info_list,
|
||||||
|
process_name, managed_nice_name, fail_fn);
|
||||||
|
insertPackagesToMergedList(env, merged_data_info_list, whitelisted_data_info_list,
|
||||||
|
process_name, managed_nice_name, fail_fn);
|
||||||
|
|
||||||
|
isolateAppData(env, merged_data_info_list, uid, process_name, managed_nice_name, fail_fn);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like isolateAppData(), isolate jit profile directories, so apps don't see what
|
* Like isolateAppData(), isolate jit profile directories, so apps don't see what
|
||||||
* other apps are installed by reading content inside /data/misc/profiles/cur.
|
* other apps are installed by reading content inside /data/misc/profiles/cur.
|
||||||
@@ -1594,7 +1612,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
|
|||||||
jstring managed_nice_name, bool is_system_server,
|
jstring managed_nice_name, bool is_system_server,
|
||||||
bool is_child_zygote, jstring managed_instruction_set,
|
bool is_child_zygote, jstring managed_instruction_set,
|
||||||
jstring managed_app_data_dir, bool is_top_app,
|
jstring managed_app_data_dir, bool is_top_app,
|
||||||
jobjectArray pkg_data_info_list, bool mount_storage_dirs) {
|
jobjectArray pkg_data_info_list,
|
||||||
|
jobjectArray whitelisted_data_info_list,
|
||||||
|
bool mount_data_dirs, bool mount_storage_dirs) {
|
||||||
const char* process_name = is_system_server ? "system_server" : "zygote";
|
const char* process_name = is_system_server ? "system_server" : "zygote";
|
||||||
auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
|
auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
|
||||||
auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
|
auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
|
||||||
@@ -1628,9 +1648,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
|
|||||||
// give a null in same_uid_pkgs and private_volumes so they don't need app data isolation.
|
// give a null in same_uid_pkgs and private_volumes so they don't need app data isolation.
|
||||||
// Isolated process / webview / app zygote should be gated by SELinux and file permission
|
// Isolated process / webview / app zygote should be gated by SELinux and file permission
|
||||||
// so they can't even traverse CE / DE directories.
|
// so they can't even traverse CE / DE directories.
|
||||||
if (pkg_data_info_list != nullptr
|
if (mount_data_dirs) {
|
||||||
&& GetBoolProperty(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true)) {
|
isolateAppData(env, pkg_data_info_list, whitelisted_data_info_list,
|
||||||
isolateAppData(env, pkg_data_info_list, uid, process_name, managed_nice_name, fail_fn);
|
uid, process_name, managed_nice_name, fail_fn);
|
||||||
isolateJitProfile(env, pkg_data_info_list, uid, process_name, managed_nice_name, fail_fn);
|
isolateJitProfile(env, pkg_data_info_list, uid, process_name, managed_nice_name, fail_fn);
|
||||||
}
|
}
|
||||||
if ((mount_external != MOUNT_EXTERNAL_INSTALLER) && mount_storage_dirs) {
|
if ((mount_external != MOUNT_EXTERNAL_INSTALLER) && mount_storage_dirs) {
|
||||||
@@ -2003,7 +2023,8 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
|
|||||||
jint mount_external, jstring se_info, jstring nice_name,
|
jint mount_external, jstring se_info, jstring nice_name,
|
||||||
jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
|
jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
|
||||||
jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
|
jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
|
||||||
jobjectArray pkg_data_info_list, jboolean mount_storage_dirs) {
|
jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list,
|
||||||
|
jboolean mount_data_dirs, jboolean mount_storage_dirs) {
|
||||||
jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
|
jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
|
||||||
|
|
||||||
if (UNLIKELY(managed_fds_to_close == nullptr)) {
|
if (UNLIKELY(managed_fds_to_close == nullptr)) {
|
||||||
@@ -2041,6 +2062,8 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
|
|||||||
mount_external, se_info, nice_name, false,
|
mount_external, se_info, nice_name, false,
|
||||||
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
|
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
|
||||||
is_top_app == JNI_TRUE, pkg_data_info_list,
|
is_top_app == JNI_TRUE, pkg_data_info_list,
|
||||||
|
whitelisted_data_info_list,
|
||||||
|
mount_data_dirs == JNI_TRUE,
|
||||||
mount_storage_dirs == JNI_TRUE);
|
mount_storage_dirs == JNI_TRUE);
|
||||||
}
|
}
|
||||||
return pid;
|
return pid;
|
||||||
@@ -2076,7 +2099,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
|
|||||||
permitted_capabilities, effective_capabilities,
|
permitted_capabilities, effective_capabilities,
|
||||||
MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
|
MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
|
||||||
false, nullptr, nullptr, /* is_top_app= */ false,
|
false, nullptr, nullptr, /* is_top_app= */ false,
|
||||||
/* pkg_data_info_list */ nullptr, false);
|
/* pkg_data_info_list */ nullptr,
|
||||||
|
/* whitelisted_data_info_list */ nullptr, false, false);
|
||||||
} else if (pid > 0) {
|
} else if (pid > 0) {
|
||||||
// The zygote process checks whether the child process has died or not.
|
// The zygote process checks whether the child process has died or not.
|
||||||
ALOGI("System server process %d has been created", pid);
|
ALOGI("System server process %d has been created", pid);
|
||||||
@@ -2206,15 +2230,16 @@ static void com_android_internal_os_Zygote_nativeSpecializeAppProcess(
|
|||||||
jint runtime_flags, jobjectArray rlimits,
|
jint runtime_flags, jobjectArray rlimits,
|
||||||
jint mount_external, jstring se_info, jstring nice_name,
|
jint mount_external, jstring se_info, jstring nice_name,
|
||||||
jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
|
jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
|
||||||
jobjectArray pkg_data_info_list, jboolean mount_storage_dirs) {
|
jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list,
|
||||||
|
jboolean mount_data_dirs, jboolean mount_storage_dirs) {
|
||||||
jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
|
jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
|
||||||
|
|
||||||
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
|
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
|
||||||
capabilities, capabilities,
|
capabilities, capabilities,
|
||||||
mount_external, se_info, nice_name, false,
|
mount_external, se_info, nice_name, false,
|
||||||
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
|
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
|
||||||
is_top_app == JNI_TRUE, pkg_data_info_list,
|
is_top_app == JNI_TRUE, pkg_data_info_list, whitelisted_data_info_list,
|
||||||
mount_storage_dirs == JNI_TRUE);
|
mount_data_dirs == JNI_TRUE, mount_storage_dirs == JNI_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2417,7 +2442,7 @@ static jboolean com_android_internal_os_Zygote_nativeSupportsTaggedPointers(JNIE
|
|||||||
static const JNINativeMethod gMethods[] = {
|
static const JNINativeMethod gMethods[] = {
|
||||||
{"nativeForkAndSpecialize",
|
{"nativeForkAndSpecialize",
|
||||||
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/"
|
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/"
|
||||||
"String;Z[Ljava/lang/String;Z)I",
|
"String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)I",
|
||||||
(void*)com_android_internal_os_Zygote_nativeForkAndSpecialize},
|
(void*)com_android_internal_os_Zygote_nativeForkAndSpecialize},
|
||||||
{"nativeForkSystemServer", "(II[II[[IJJ)I",
|
{"nativeForkSystemServer", "(II[II[[IJJ)I",
|
||||||
(void*)com_android_internal_os_Zygote_nativeForkSystemServer},
|
(void*)com_android_internal_os_Zygote_nativeForkSystemServer},
|
||||||
@@ -2430,7 +2455,7 @@ static const JNINativeMethod gMethods[] = {
|
|||||||
{"nativeForkUsap", "(II[IZ)I", (void*)com_android_internal_os_Zygote_nativeForkUsap},
|
{"nativeForkUsap", "(II[IZ)I", (void*)com_android_internal_os_Zygote_nativeForkUsap},
|
||||||
{"nativeSpecializeAppProcess",
|
{"nativeSpecializeAppProcess",
|
||||||
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/"
|
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/"
|
||||||
"String;Z[Ljava/lang/String;Z)V",
|
"String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)V",
|
||||||
(void*)com_android_internal_os_Zygote_nativeSpecializeAppProcess},
|
(void*)com_android_internal_os_Zygote_nativeSpecializeAppProcess},
|
||||||
{"nativeInitNativeState", "(Z)V",
|
{"nativeInitNativeState", "(Z)V",
|
||||||
(void*)com_android_internal_os_Zygote_nativeInitNativeState},
|
(void*)com_android_internal_os_Zygote_nativeInitNativeState},
|
||||||
|
|||||||
@@ -4468,9 +4468,8 @@ class StorageManagerService extends IStorageManager.Stub
|
|||||||
String.format("/storage/emulated/%d/Android/data/%s/",
|
String.format("/storage/emulated/%d/Android/data/%s/",
|
||||||
userId, pkg);
|
userId, pkg);
|
||||||
|
|
||||||
int appUid =
|
|
||||||
UserHandle.getUid(userId, mPmInternal.getPackage(pkg).getUid());
|
|
||||||
// Create package obb and data dir if it doesn't exist.
|
// Create package obb and data dir if it doesn't exist.
|
||||||
|
int appUid = UserHandle.getUid(userId, mPmInternal.getPackage(pkg).getUid());
|
||||||
File file = new File(packageObbDir);
|
File file = new File(packageObbDir);
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
vold.setupAppDir(packageObbDir, appUid);
|
vold.setupAppDir(packageObbDir, appUid);
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ import android.os.storage.StorageManagerInternal;
|
|||||||
import android.system.Os;
|
import android.system.Os;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
|
import android.util.ArraySet;
|
||||||
import android.util.EventLog;
|
import android.util.EventLog;
|
||||||
import android.util.LongSparseArray;
|
import android.util.LongSparseArray;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
@@ -137,6 +138,7 @@ import java.util.BitSet;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity manager code dealing with processes.
|
* Activity manager code dealing with processes.
|
||||||
@@ -2129,18 +2131,11 @@ public final class ProcessList {
|
|||||||
for (String packageName : packages) {
|
for (String packageName : packages) {
|
||||||
String volumeUuid = pmInt.getPackage(packageName).getVolumeUuid();
|
String volumeUuid = pmInt.getPackage(packageName).getVolumeUuid();
|
||||||
long inode = pmInt.getCeDataInode(packageName, userId);
|
long inode = pmInt.getCeDataInode(packageName, userId);
|
||||||
if (inode != 0) {
|
if (inode == 0) {
|
||||||
result.put(packageName, Pair.create(volumeUuid, inode));
|
Slog.w(TAG, packageName + " inode == 0 (b/152760674)");
|
||||||
}
|
return null;
|
||||||
}
|
|
||||||
if (mAppDataIsolationWhitelistedApps != null) {
|
|
||||||
for (String packageName : mAppDataIsolationWhitelistedApps) {
|
|
||||||
String volumeUuid = pmInt.getPackage(packageName).getVolumeUuid();
|
|
||||||
long inode = pmInt.getCeDataInode(packageName, userId);
|
|
||||||
if (inode != 0) {
|
|
||||||
result.put(packageName, Pair.create(volumeUuid, inode));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
result.put(packageName, Pair.create(volumeUuid, inode));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -2162,35 +2157,56 @@ public final class ProcessList {
|
|||||||
app.setHasForegroundActivities(true);
|
app.setHasForegroundActivities(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Map<String, Pair<String, Long>> pkgDataInfoMap;
|
||||||
|
final Map<String, Pair<String, Long>> whitelistedAppDataInfoMap;
|
||||||
|
boolean bindMountAppStorageDirs = false;
|
||||||
|
boolean bindMountAppsData = mAppDataIsolationEnabled
|
||||||
|
&& UserHandle.isApp(app.uid)
|
||||||
|
&& mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info);
|
||||||
|
|
||||||
|
// Get all packages belongs to the same shared uid. sharedPackages is empty array
|
||||||
|
// if it doesn't have shared uid.
|
||||||
|
final PackageManagerInternal pmInt = mService.getPackageManagerInternalLocked();
|
||||||
|
final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage(
|
||||||
|
app.info.packageName, app.userId);
|
||||||
|
final String[] targetPackagesList = sharedPackages.length == 0
|
||||||
|
? new String[]{app.info.packageName} : sharedPackages;
|
||||||
|
|
||||||
|
pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, targetPackagesList, uid);
|
||||||
|
if (pkgDataInfoMap == null) {
|
||||||
|
// TODO(b/152760674): Handle inode == 0 case properly, now we just give it a
|
||||||
|
// tmp free pass.
|
||||||
|
bindMountAppsData = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all packages in pkgDataInfoMap from mAppDataIsolationWhitelistedApps, so
|
||||||
|
// it won't be mounted twice.
|
||||||
|
final Set<String> whitelistedApps = new ArraySet<>(mAppDataIsolationWhitelistedApps);
|
||||||
|
for (String pkg : targetPackagesList) {
|
||||||
|
whitelistedApps.remove(pkg);
|
||||||
|
}
|
||||||
|
|
||||||
|
whitelistedAppDataInfoMap = getPackageAppDataInfoMap(pmInt,
|
||||||
|
whitelistedApps.toArray(new String[0]), uid);
|
||||||
|
if (whitelistedAppDataInfoMap == null) {
|
||||||
|
// TODO(b/152760674): Handle inode == 0 case properly, now we just give it a
|
||||||
|
// tmp free pass.
|
||||||
|
bindMountAppsData = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int userId = UserHandle.getUserId(uid);
|
||||||
StorageManagerInternal storageManagerInternal = LocalServices.getService(
|
StorageManagerInternal storageManagerInternal = LocalServices.getService(
|
||||||
StorageManagerInternal.class);
|
StorageManagerInternal.class);
|
||||||
final Map<String, Pair<String, Long>> pkgDataInfoMap;
|
if (mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid)
|
||||||
boolean bindMountAppStorageDirs = false;
|
&& !storageManagerInternal.isExternalStorageService(uid)) {
|
||||||
|
bindMountAppStorageDirs = true;
|
||||||
if (mAppDataIsolationEnabled && UserHandle.isApp(app.uid)
|
if (!storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
|
||||||
&& mPlatformCompat.isChangeEnabled(APP_DATA_DIRECTORY_ISOLATION, app.info)) {
|
app.processName)) {
|
||||||
// Get all packages belongs to the same shared uid. sharedPackages is empty array
|
// Cannot prepare Android/app and Android/obb directory,
|
||||||
// if it doesn't have shared uid.
|
// so we won't mount it in zygote.
|
||||||
final PackageManagerInternal pmInt = mService.getPackageManagerInternalLocked();
|
app.bindMountPending = true;
|
||||||
final String[] sharedPackages = pmInt.getSharedUserPackagesForPackage(
|
bindMountAppStorageDirs = false;
|
||||||
app.info.packageName, app.userId);
|
|
||||||
pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, sharedPackages.length == 0
|
|
||||||
? new String[]{app.info.packageName} : sharedPackages, uid);
|
|
||||||
|
|
||||||
int userId = UserHandle.getUserId(uid);
|
|
||||||
if (mVoldAppDataIsolationEnabled
|
|
||||||
&& !storageManagerInternal.isExternalStorageService(uid)) {
|
|
||||||
bindMountAppStorageDirs = true;
|
|
||||||
if (!storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
|
|
||||||
app.processName)) {
|
|
||||||
// Cannot prepare Android/app and Android/obb directory,
|
|
||||||
// so we won't mount it in zygote.
|
|
||||||
app.bindMountPending = true;
|
|
||||||
bindMountAppStorageDirs = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
pkgDataInfoMap = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Process.ProcessStartResult startResult;
|
final Process.ProcessStartResult startResult;
|
||||||
@@ -2208,7 +2224,8 @@ public final class ProcessList {
|
|||||||
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
|
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
|
||||||
app.info.dataDir, null, app.info.packageName,
|
app.info.dataDir, null, app.info.packageName,
|
||||||
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
|
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
|
||||||
app.mDisabledCompatChanges, pkgDataInfoMap, bindMountAppStorageDirs,
|
app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
|
||||||
|
bindMountAppsData, bindMountAppStorageDirs,
|
||||||
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
|
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
|
||||||
} else {
|
} else {
|
||||||
startResult = Process.start(entryPoint,
|
startResult = Process.start(entryPoint,
|
||||||
@@ -2216,7 +2233,7 @@ public final class ProcessList {
|
|||||||
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
|
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
|
||||||
app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
|
app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
|
||||||
isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
|
isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
|
||||||
bindMountAppStorageDirs,
|
whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
|
||||||
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
|
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
|
||||||
}
|
}
|
||||||
checkSlow(startTime, "startProcess: returned from zygote!");
|
checkSlow(startTime, "startProcess: returned from zygote!");
|
||||||
|
|||||||
Reference in New Issue
Block a user