Pass the packageName to zygote when starting a new process.
This packageName is passed so that the process initialization
after the zygote fork can mount appropriate package sandbox.
Bug: 111890351
Test: n/a
Change-Id: I99d6c1b53fffd53d7387dc807106efe5e1dc9b07
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 7ce7c92..7caf0b1 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -492,10 +492,11 @@
String instructionSet,
String appDataDir,
String invokeWith,
+ String packageName,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
- abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
+ abi, instructionSet, appDataDir, invokeWith, packageName, zygoteArgs);
}
/** @hide */
@@ -509,10 +510,11 @@
String instructionSet,
String appDataDir,
String invokeWith,
+ String packageName,
String[] zygoteArgs) {
return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
- abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
+ abi, instructionSet, appDataDir, invokeWith, packageName, zygoteArgs);
}
/**
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 021e72f..067e849 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -227,12 +227,13 @@
String instructionSet,
String appDataDir,
String invokeWith,
+ String packageName,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
- zygoteArgs);
+ packageName, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -366,6 +367,7 @@
String appDataDir,
String invokeWith,
boolean startChildZygote,
+ String packageName,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
@@ -426,6 +428,10 @@
argsForZygote.add("--start-child-zygote");
}
+ if (packageName != null) {
+ argsForZygote.add("--package-name=" + packageName);
+ }
+
argsForZygote.add(processClass);
if (extraArgs != null) {
@@ -733,7 +739,7 @@
result = startViaZygote(processClass, niceName, uid, gid,
gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
- true /* startChildZygote */, extraArgs);
+ true /* startChildZygote */, null /* packageName */, extraArgs);
} catch (ZygoteStartFailedEx ex) {
throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 4ee950a..413f89d 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -132,13 +132,14 @@
*/
public 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) {
+ int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
+ String packageName) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
- fdsToIgnore, startChildZygote, instructionSet, appDataDir);
+ fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName);
// Enable tracing as soon as possible for the child process.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
@@ -152,7 +153,8 @@
native private static int nativeForkAndSpecialize(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);
+ int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
+ String packageName);
/**
* Called to do any initialization before starting an application.
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 12761b9..b9c717f 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -239,7 +239,7 @@
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
- parsedArgs.instructionSet, parsedArgs.appDataDir);
+ parsedArgs.instructionSet, parsedArgs.appDataDir, parsedArgs.packageName);
try {
if (pid == 0) {
@@ -426,6 +426,9 @@
/** from --invoke-with */
String invokeWith;
+ /** from --package-name */
+ String packageName;
+
/**
* Any args after and including the first non-option arg
* (or after a '--')
@@ -674,6 +677,8 @@
"Invalid log sampling rate: " + rateStr, nfe);
}
expectRuntimeArgs = false;
+ } else if (arg.startsWith("--package-name=")) {
+ packageName = arg.substring(arg.indexOf('=') + 1);
} else {
break;
}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 0022cf88..daf15e9 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -382,7 +382,7 @@
// Create a private mount namespace and bind mount appropriate emulated
// storage for the given user.
static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
- bool force_mount_namespace, std::string* error_msg) {
+ bool force_mount_namespace, std::string* error_msg, const char* package_name) {
// See storage config details at http://source.android.com/tech/storage/
String8 storageSource;
@@ -544,7 +544,7 @@
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external, jstring java_se_info, jstring java_se_name,
bool is_system_server, bool is_child_zygote, jstring instructionSet,
- jstring dataDir) {
+ jstring dataDir, jstring packageName) {
std::string error_msg;
auto fail_fn = [env, java_se_name, is_system_server](const std::string& msg)
@@ -594,7 +594,18 @@
ALOGW("Native bridge will not be used because dataDir == NULL.");
}
- if (!MountEmulatedStorage(uid, mount_external, use_native_bridge, &error_msg)) {
+ ScopedUtfChars* package_name = nullptr;
+ const char* package_name_c_str = nullptr;
+ if (packageName != nullptr) {
+ package_name = new ScopedUtfChars(env, packageName);
+ package_name_c_str = package_name->c_str();
+ } else if (is_system_server) {
+ package_name_c_str = "android";
+ }
+ bool success = MountEmulatedStorage(uid, mount_external, use_native_bridge, &error_msg,
+ package_name_c_str);
+ delete package_name;
+ if (!success) {
ALOGW("Failed to mount emulated storage: %s (%s)", error_msg.c_str(), strerror(errno));
if (errno == ENOTCONN || errno == EROFS) {
// When device is actively encrypting, we get ENOTCONN here
@@ -858,7 +869,7 @@
jint runtime_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote,
- jstring instructionSet, jstring appDataDir) {
+ jstring instructionSet, jstring appDataDir, jstring packageName) {
jlong capabilities = 0;
// Grant CAP_WAKE_ALARM to the Bluetooth process.
@@ -911,7 +922,7 @@
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
capabilities, capabilities,
mount_external, se_info, se_name, false,
- is_child_zygote == JNI_TRUE, instructionSet, appDataDir);
+ is_child_zygote == JNI_TRUE, instructionSet, appDataDir, packageName);
}
return pid;
}
@@ -925,7 +936,7 @@
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true,
- false, NULL, NULL);
+ false, NULL, NULL, nullptr);
} 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);
@@ -1006,7 +1017,7 @@
{ "nativeSecurityInit", "()V",
(void *) com_android_internal_os_Zygote_nativeSecurityInit },
{ "nativeForkAndSpecialize",
- "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I",
+ "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
(void *) com_android_internal_os_Zygote_nativeForkSystemServer },
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 594b391..765b954 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3688,13 +3688,13 @@
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
- app.info.dataDir, null,
+ app.info.dataDir, null, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
- app.info.dataDir, invokeWith,
+ app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkTime(startTime, "startProcess: returned from zygote!");