Merge "Revert "Revert "Do not mount whitelisted package in storage data and obb dirs""" into rvc-dev am: afef06a0f6
Change-Id: I776199e8816b798a8302e087155a0629b6b5ccc4
This commit is contained in:
@@ -607,6 +607,9 @@ public class Process {
|
||||
* started.
|
||||
* @param pkgDataInfoMap Map from related package names to private data directory
|
||||
* 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 zygoteArgs Additional arguments to supply to the zygote 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 Map<String, Pair<String, Long>>
|
||||
pkgDataInfoMap,
|
||||
@Nullable Map<String, Pair<String, Long>>
|
||||
whitelistedDataInfoMap,
|
||||
boolean bindMountAppsData,
|
||||
boolean bindMountAppStorageDirs,
|
||||
@Nullable String[] zygoteArgs) {
|
||||
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
|
||||
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
||||
abi, instructionSet, appDataDir, invokeWith, packageName,
|
||||
zygotePolicyFlags, isTopApp, disabledCompatChanges,
|
||||
pkgDataInfoMap, bindMountAppStorageDirs, zygoteArgs);
|
||||
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
|
||||
bindMountAppStorageDirs, zygoteArgs);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -661,7 +668,8 @@ public class Process {
|
||||
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
||||
abi, instructionSet, appDataDir, invokeWith, packageName,
|
||||
/*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.
|
||||
* @param pkgDataInfoMap Map from related package names to private data directory
|
||||
* 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 zygoteArgs Additional arguments to supply to the Zygote process.
|
||||
@@ -355,6 +358,9 @@ public class ZygoteProcess {
|
||||
@Nullable long[] disabledCompatChanges,
|
||||
@Nullable Map<String, Pair<String, Long>>
|
||||
pkgDataInfoMap,
|
||||
@Nullable Map<String, Pair<String, Long>>
|
||||
whitelistedDataInfoMap,
|
||||
boolean bindMountAppsData,
|
||||
boolean bindMountAppStorageDirs,
|
||||
@Nullable String[] zygoteArgs) {
|
||||
// TODO (chriswailes): Is there a better place to check this value?
|
||||
@@ -367,7 +373,8 @@ public class ZygoteProcess {
|
||||
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
|
||||
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
|
||||
packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
|
||||
pkgDataInfoMap, bindMountAppStorageDirs, zygoteArgs);
|
||||
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
|
||||
bindMountAppStorageDirs, zygoteArgs);
|
||||
} catch (ZygoteStartFailedEx ex) {
|
||||
Log.e(LOG_TAG,
|
||||
"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 pkgDataInfoMap Map from related package names to private data directory 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 extraArgs Additional arguments to supply to the zygote 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 Map<String, Pair<String, Long>>
|
||||
pkgDataInfoMap,
|
||||
@Nullable Map<String, Pair<String, Long>>
|
||||
whitelistedDataInfoMap,
|
||||
boolean bindMountAppsData,
|
||||
boolean bindMountAppStorageDirs,
|
||||
@Nullable String[] extraArgs)
|
||||
throws ZygoteStartFailedEx {
|
||||
@@ -728,11 +741,33 @@ public class ZygoteProcess {
|
||||
}
|
||||
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) {
|
||||
argsForZygote.add(Zygote.BIND_MOUNT_APP_STORAGE_DIRS);
|
||||
}
|
||||
|
||||
if (bindMountAppsData) {
|
||||
argsForZygote.add(Zygote.BIND_MOUNT_APP_DATA_DIRS);
|
||||
}
|
||||
|
||||
if (disabledCompatChanges != null && disabledCompatChanges.length > 0) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("--disabled-compat-changes=");
|
||||
@@ -1291,6 +1326,7 @@ public class ZygoteProcess {
|
||||
true /* startChildZygote */, null /* packageName */,
|
||||
ZYGOTE_POLICY_FLAG_SYSTEM_PROCESS /* zygotePolicyFlags */, false /* isTopApp */,
|
||||
null /* disabledCompatChanges */, null /* pkgDataInfoMap */,
|
||||
null /* whitelistedDataInfoMap */, false /* bindMountAppsData*/,
|
||||
/* bindMountAppStorageDirs */ false, extraArgs);
|
||||
|
||||
} 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. */
|
||||
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 */
|
||||
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
|
||||
* 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 pkgDataInfoList A list that stores related packages and its app data
|
||||
* 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.
|
||||
*
|
||||
* @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,
|
||||
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
|
||||
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();
|
||||
|
||||
int pid = nativeForkAndSpecialize(
|
||||
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
|
||||
fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
|
||||
pkgDataInfoList, bindMountAppStorageDirs);
|
||||
pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,
|
||||
bindMountAppStorageDirs);
|
||||
if (pid == 0) {
|
||||
// Note that this event ends at the end of handleChildProc,
|
||||
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[] fdsToClose, int[] fdsToIgnore, boolean startChildZygote, String instructionSet,
|
||||
String appDataDir, boolean isTopApp, String[] pkgDataInfoList,
|
||||
String[] whitelistedDataInfoList, boolean bindMountAppDataDirs,
|
||||
boolean bindMountAppStorageDirs);
|
||||
|
||||
/**
|
||||
@@ -371,15 +382,19 @@ public final class Zygote {
|
||||
* 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_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.
|
||||
*/
|
||||
private static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,
|
||||
int[][] rlimits, int mountExternal, String seInfo, String niceName,
|
||||
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,
|
||||
niceName, startChildZygote, instructionSet, appDataDir, isTopApp,
|
||||
pkgDataInfoList, bindMountAppStorageDirs);
|
||||
pkgDataInfoList, whitelistedDataInfoList,
|
||||
bindMountAppDataDirs, bindMountAppStorageDirs);
|
||||
|
||||
// Note that this event ends at the end of handleChildProc.
|
||||
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,
|
||||
int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
|
||||
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.
|
||||
@@ -724,7 +740,8 @@ public final class Zygote {
|
||||
args.mRuntimeFlags, rlimits, args.mMountExternal,
|
||||
args.mSeInfo, args.mNiceName, args.mStartChildZygote,
|
||||
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);
|
||||
|
||||
|
||||
@@ -226,11 +226,22 @@ class ZygoteArguments {
|
||||
*/
|
||||
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
|
||||
*/
|
||||
boolean mBindMountAppStorageDirs;
|
||||
|
||||
/**
|
||||
* @see Zygote#BIND_MOUNT_APP_DATA_DIRS
|
||||
*/
|
||||
boolean mBindMountAppDataDirs;
|
||||
|
||||
/**
|
||||
* Constructs instance and parses args
|
||||
*
|
||||
@@ -452,8 +463,12 @@ class ZygoteArguments {
|
||||
}
|
||||
} else if (arg.startsWith(Zygote.PKG_DATA_INFO_MAP)) {
|
||||
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)) {
|
||||
mBindMountAppStorageDirs = true;
|
||||
} else if (arg.equals(Zygote.BIND_MOUNT_APP_DATA_DIRS)) {
|
||||
mBindMountAppDataDirs = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -258,7 +258,8 @@ class ZygoteConnection {
|
||||
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
|
||||
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
|
||||
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
|
||||
parsedArgs.mPkgDataInfoList, parsedArgs.mBindMountAppStorageDirs);
|
||||
parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
|
||||
parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
|
||||
|
||||
try {
|
||||
if (pid == 0) {
|
||||
|
||||
@@ -110,7 +110,6 @@ using android::base::StringAppendF;
|
||||
using android::base::StringPrintf;
|
||||
using android::base::WriteStringToFile;
|
||||
using android::base::GetBoolProperty;
|
||||
using android::base::GetProperty;
|
||||
|
||||
#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \
|
||||
append(StringPrintf(__VA_ARGS__))
|
||||
@@ -170,18 +169,6 @@ static int gSystemServerSocketFd = -1;
|
||||
|
||||
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 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.
|
||||
*
|
||||
*/
|
||||
static void isolateAppData(JNIEnv* env, jobjectArray pkg_data_info_list,
|
||||
uid_t uid, const char* process_name, jstring managed_nice_name,
|
||||
fail_fn_t fail_fn) {
|
||||
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, fail_fn_t fail_fn) {
|
||||
|
||||
const userid_t userId = multiuser_get_user_id(uid);
|
||||
|
||||
auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
|
||||
|
||||
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);
|
||||
int size = merged_data_info_list.size();
|
||||
|
||||
// Mount tmpfs on all possible data directories, so app no longer see the original apps data.
|
||||
char internalCePath[PATH_MAX];
|
||||
@@ -1377,14 +1357,10 @@ static void isolateAppData(JNIEnv* env, jobjectArray pkg_data_info_list,
|
||||
bool legacySymlinkCreated = false;
|
||||
|
||||
for (int i = 0; i < size; i += 3) {
|
||||
jstring package_str = (jstring) (env->GetObjectArrayElement(pkg_data_info_list, i));
|
||||
std::string packageName = extract_fn(package_str).value();
|
||||
std::string const & packageName = merged_data_info_list[i];
|
||||
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;
|
||||
long long ceDataInode = std::stoll(inode, &sz);
|
||||
|
||||
@@ -1482,6 +1458,48 @@ static void isolateAppData(JNIEnv* env, jobjectArray pkg_data_info_list,
|
||||
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
|
||||
* 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,
|
||||
bool is_child_zygote, jstring managed_instruction_set,
|
||||
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";
|
||||
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);
|
||||
@@ -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.
|
||||
// Isolated process / webview / app zygote should be gated by SELinux and file permission
|
||||
// so they can't even traverse CE / DE directories.
|
||||
if (pkg_data_info_list != nullptr
|
||||
&& GetBoolProperty(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true)) {
|
||||
isolateAppData(env, pkg_data_info_list, uid, process_name, managed_nice_name, fail_fn);
|
||||
if (mount_data_dirs) {
|
||||
isolateAppData(env, pkg_data_info_list, whitelisted_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) {
|
||||
@@ -2003,7 +2023,8 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
|
||||
jint mount_external, jstring se_info, jstring nice_name,
|
||||
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,
|
||||
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);
|
||||
|
||||
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,
|
||||
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
|
||||
is_top_app == JNI_TRUE, pkg_data_info_list,
|
||||
whitelisted_data_info_list,
|
||||
mount_data_dirs == JNI_TRUE,
|
||||
mount_storage_dirs == JNI_TRUE);
|
||||
}
|
||||
return pid;
|
||||
@@ -2076,7 +2099,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
|
||||
permitted_capabilities, effective_capabilities,
|
||||
MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
|
||||
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) {
|
||||
// The zygote process checks whether the child process has died or not.
|
||||
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 mount_external, jstring se_info, jstring nice_name,
|
||||
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);
|
||||
|
||||
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
|
||||
capabilities, capabilities,
|
||||
mount_external, se_info, nice_name, false,
|
||||
is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
|
||||
is_top_app == JNI_TRUE, pkg_data_info_list,
|
||||
mount_storage_dirs == JNI_TRUE);
|
||||
is_top_app == JNI_TRUE, pkg_data_info_list, whitelisted_data_info_list,
|
||||
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[] = {
|
||||
{"nativeForkAndSpecialize",
|
||||
"(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},
|
||||
{"nativeForkSystemServer", "(II[II[[IJJ)I",
|
||||
(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},
|
||||
{"nativeSpecializeAppProcess",
|
||||
"(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},
|
||||
{"nativeInitNativeState", "(Z)V",
|
||||
(void*)com_android_internal_os_Zygote_nativeInitNativeState},
|
||||
|
||||
@@ -4468,9 +4468,8 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
String.format("/storage/emulated/%d/Android/data/%s/",
|
||||
userId, pkg);
|
||||
|
||||
int appUid =
|
||||
UserHandle.getUid(userId, mPmInternal.getPackage(pkg).getUid());
|
||||
// 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);
|
||||
if (!file.exists()) {
|
||||
vold.setupAppDir(packageObbDir, appUid);
|
||||
|
||||
@@ -97,6 +97,7 @@ import android.os.storage.StorageManagerInternal;
|
||||
import android.system.Os;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.EventLog;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.Pair;
|
||||
@@ -137,6 +138,7 @@ import java.util.BitSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Activity manager code dealing with processes.
|
||||
@@ -2129,18 +2131,11 @@ public final class ProcessList {
|
||||
for (String packageName : packages) {
|
||||
String volumeUuid = pmInt.getPackage(packageName).getVolumeUuid();
|
||||
long inode = pmInt.getCeDataInode(packageName, userId);
|
||||
if (inode != 0) {
|
||||
result.put(packageName, Pair.create(volumeUuid, inode));
|
||||
}
|
||||
}
|
||||
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));
|
||||
}
|
||||
if (inode == 0) {
|
||||
Slog.w(TAG, packageName + " inode == 0 (b/152760674)");
|
||||
return null;
|
||||
}
|
||||
result.put(packageName, Pair.create(volumeUuid, inode));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -2162,35 +2157,56 @@ public final class ProcessList {
|
||||
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.class);
|
||||
final Map<String, Pair<String, Long>> pkgDataInfoMap;
|
||||
boolean bindMountAppStorageDirs = false;
|
||||
|
||||
if (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);
|
||||
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;
|
||||
}
|
||||
if (mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid)
|
||||
&& !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;
|
||||
@@ -2208,7 +2224,8 @@ public final class ProcessList {
|
||||
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
|
||||
app.info.dataDir, null, app.info.packageName,
|
||||
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
|
||||
app.mDisabledCompatChanges, pkgDataInfoMap, bindMountAppStorageDirs,
|
||||
app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
|
||||
bindMountAppsData, bindMountAppStorageDirs,
|
||||
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
|
||||
} else {
|
||||
startResult = Process.start(entryPoint,
|
||||
@@ -2216,7 +2233,7 @@ public final class ProcessList {
|
||||
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
|
||||
app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
|
||||
isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
|
||||
bindMountAppStorageDirs,
|
||||
whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
|
||||
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
|
||||
}
|
||||
checkSlow(startTime, "startProcess: returned from zygote!");
|
||||
|
||||
Reference in New Issue
Block a user