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:
TreeHugger Robot
2020-04-08 15:04:20 +00:00
committed by Automerger Merge Worker
8 changed files with 211 additions and 93 deletions

View File

@@ -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);
}
/**

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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},

View File

@@ -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);

View File

@@ -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!");