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