Skip to content

Commit 2086787

Browse files
gujinghuiagampe
authored andcommitted
Frameworks/base: Early init native bridge
Add the app directory to the arguments for starting a process. Add a check for NeedsNativeBridge and a call to PreInitializeBridge in the native fork code. (cherry picked from commit 2eacd06) Bug: 17671501 Change-Id: I970db5b284b0c12e2d8a45df3950c1fff2927a4e
1 parent 8120652 commit 2086787

5 files changed

Lines changed: 139 additions & 97 deletions

File tree

core/java/android/os/Process.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ boolean isClosed() {
469469
* @param seInfo null-ok SELinux information for the new process.
470470
* @param abi non-null the ABI this app should be started with.
471471
* @param instructionSet null-ok the instruction set to use.
472+
* @param appDataDir null-ok the data directory of the app.
472473
* @param zygoteArgs Additional arguments to supply to the zygote process.
473474
*
474475
* @return An object that describes the result of the attempt to start the process.
@@ -484,11 +485,12 @@ public static final ProcessStartResult start(final String processClass,
484485
String seInfo,
485486
String abi,
486487
String instructionSet,
488+
String appDataDir,
487489
String[] zygoteArgs) {
488490
try {
489491
return startViaZygote(processClass, niceName, uid, gid, gids,
490492
debugFlags, mountExternal, targetSdkVersion, seInfo,
491-
abi, instructionSet, zygoteArgs);
493+
abi, instructionSet, appDataDir, zygoteArgs);
492494
} catch (ZygoteStartFailedEx ex) {
493495
Log.e(LOG_TAG,
494496
"Starting VM process through Zygote failed");
@@ -592,6 +594,7 @@ private static ProcessStartResult zygoteSendArgsAndGetResult(
592594
* @param seInfo null-ok SELinux information for the new process.
593595
* @param abi the ABI the process should use.
594596
* @param instructionSet null-ok the instruction set to use.
597+
* @param appDataDir null-ok the data directory of the app.
595598
* @param extraArgs Additional arguments to supply to the zygote process.
596599
* @return An object that describes the result of the attempt to start the process.
597600
* @throws ZygoteStartFailedEx if process start failed for any reason
@@ -605,6 +608,7 @@ private static ProcessStartResult startViaZygote(final String processClass,
605608
String seInfo,
606609
String abi,
607610
String instructionSet,
611+
String appDataDir,
608612
String[] extraArgs)
609613
throws ZygoteStartFailedEx {
610614
synchronized(Process.class) {
@@ -668,6 +672,10 @@ private static ProcessStartResult startViaZygote(final String processClass,
668672
argsForZygote.add("--instruction-set=" + instructionSet);
669673
}
670674

675+
if (appDataDir != null) {
676+
argsForZygote.add("--app-data-dir=" + appDataDir);
677+
}
678+
671679
argsForZygote.add(processClass);
672680

673681
if (extraArgs != null) {

core/java/com/android/internal/os/Zygote.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,20 @@ private Zygote() {}
7979
* (and replaced by /dev/null) after forking. An integer value
8080
* of -1 in any entry in the array means "ignore this one".
8181
* @param instructionSet null-ok the instruction set to use.
82+
* @param appDataDir null-ok the data directory of the app.
8283
*
8384
* @return 0 if this is the child, pid of the child
8485
* if this is the parent, or -1 on error.
8586
*/
8687
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
8788
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
88-
String instructionSet) {
89+
String instructionSet, String appDataDir) {
8990
long startTime = SystemClock.elapsedRealtime();
9091
VM_HOOKS.preFork();
9192
checkTime(startTime, "Zygote.preFork");
9293
int pid = nativeForkAndSpecialize(
9394
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
94-
instructionSet);
95+
instructionSet, appDataDir);
9596
checkTime(startTime, "Zygote.nativeForkAndSpecialize");
9697
VM_HOOKS.postForkCommon();
9798
checkTime(startTime, "Zygote.postForkCommon");
@@ -100,7 +101,7 @@ public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags
100101

101102
native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
102103
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
103-
String instructionSet);
104+
String instructionSet, String appDataDir);
104105

105106
/**
106107
* Temporary hack: check time since start time and log if over a fixed threshold.

core/java/com/android/internal/os/ZygoteConnection.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class ZygoteConnection {
9393
new InputStreamReader(socket.getInputStream()), 256);
9494

9595
mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);
96-
96+
9797
try {
9898
peer = mSocket.getPeerCredentials();
9999
} catch (IOException ex) {
@@ -245,7 +245,8 @@ boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
245245
checkTime(startTime, "zygoteConnection.runOnce: preForkAndSpecialize");
246246
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
247247
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
248-
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet);
248+
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
249+
parsedArgs.appDataDir);
249250
checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize");
250251
} catch (IOException ex) {
251252
logAndPrintError(newStderr, "Exception creating pipe", ex);
@@ -403,6 +404,12 @@ static class Arguments {
403404
*/
404405
String instructionSet;
405406

407+
/**
408+
* The app data directory. May be null, e.g., for the system server. Note that this might
409+
* not be reliable in the case of process-sharing apps.
410+
*/
411+
String appDataDir;
412+
406413
/**
407414
* Constructs instance and parses args
408415
* @param args zygote command-line args
@@ -560,6 +567,8 @@ private void parseArgs(String args[])
560567
abiListQuery = true;
561568
} else if (arg.startsWith("--instruction-set=")) {
562569
instructionSet = arg.substring(arg.indexOf('=') + 1);
570+
} else if (arg.startsWith("--app-data-dir=")) {
571+
appDataDir = arg.substring(arg.indexOf('=') + 1);
563572
} else {
564573
break;
565574
}
@@ -611,7 +620,7 @@ private String[] readArgumentList()
611620
}
612621

613622
// See bug 1092107: large argc can be used for a DOS attack
614-
if (argc > MAX_ZYGOTE_ARGC) {
623+
if (argc > MAX_ZYGOTE_ARGC) {
615624
throw new IOException("max arg count exceeded");
616625
}
617626

@@ -628,7 +637,7 @@ private String[] readArgumentList()
628637
}
629638

630639
/**
631-
* Applies zygote security policy per bugs #875058 and #1082165.
640+
* Applies zygote security policy per bugs #875058 and #1082165.
632641
* Based on the credentials of the process issuing a zygote command:
633642
* <ol>
634643
* <li> uid 0 (root) may specify any uid, gid, and setgroups() list
@@ -659,7 +668,7 @@ private static void applyUidSecurityPolicy(Arguments args, Credentials peer,
659668
/* In normal operation, SYSTEM_UID can only specify a restricted
660669
* set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
661670
*/
662-
uidRestricted
671+
uidRestricted
663672
= !(factoryTest.equals("1") || factoryTest.equals("2"));
664673

665674
if (uidRestricted

core/jni/com_android_internal_os_Zygote.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
#include "ScopedPrimitiveArray.h"
5252
#include "ScopedUtfChars.h"
5353

54+
#include "nativebridge/native_bridge.h"
55+
5456
namespace {
5557

5658
using android::String8;
@@ -249,20 +251,24 @@ static void SetSchedulerPolicy(JNIEnv* env) {
249251

250252
// Create a private mount namespace and bind mount appropriate emulated
251253
// storage for the given user.
252-
static bool MountEmulatedStorage(uid_t uid, jint mount_mode) {
253-
if (mount_mode == MOUNT_EXTERNAL_NONE) {
254+
static bool MountEmulatedStorage(uid_t uid, jint mount_mode, bool force_mount_namespace) {
255+
if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
254256
return true;
255257
}
256258

257-
// See storage config details at http://source.android.com/tech/storage/
258-
userid_t user_id = multiuser_get_user_id(uid);
259-
260259
// Create a second private mount namespace for our process
261260
if (unshare(CLONE_NEWNS) == -1) {
262261
ALOGW("Failed to unshare(): %d", errno);
263262
return false;
264263
}
265264

265+
if (mount_mode == MOUNT_EXTERNAL_NONE) {
266+
return true;
267+
}
268+
269+
// See storage config details at http://source.android.com/tech/storage/
270+
userid_t user_id = multiuser_get_user_id(uid);
271+
266272
// Create bind mounts to expose external storage
267273
if (mount_mode == MOUNT_EXTERNAL_MULTIUSER || mount_mode == MOUNT_EXTERNAL_MULTIUSER_ALL) {
268274
// These paths must already be created by init.rc
@@ -422,7 +428,7 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
422428
jint mount_external,
423429
jstring java_se_info, jstring java_se_name,
424430
bool is_system_server, jintArray fdsToClose,
425-
jstring instructionSet) {
431+
jstring instructionSet, jstring dataDir) {
426432
uint64_t start = MsTime();
427433
SetSigChldHandler();
428434
ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler");
@@ -446,7 +452,13 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
446452

447453
DropCapabilitiesBoundingSet(env);
448454

449-
if (!MountEmulatedStorage(uid, mount_external)) {
455+
bool need_native_bridge = false;
456+
if (instructionSet != NULL) {
457+
ScopedUtfChars isa_string(env, instructionSet);
458+
need_native_bridge = android::NeedsNativeBridge(isa_string.c_str());
459+
}
460+
461+
if (!MountEmulatedStorage(uid, mount_external, need_native_bridge)) {
450462
ALOGW("Failed to mount emulated storage: %d", errno);
451463
if (errno == ENOTCONN || errno == EROFS) {
452464
// When device is actively encrypting, we get ENOTCONN here
@@ -475,6 +487,17 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
475487

476488
SetRLimits(env, javaRlimits);
477489

490+
if (!is_system_server && need_native_bridge) {
491+
// Set the environment for the apps running with native bridge.
492+
ScopedUtfChars isa_string(env, instructionSet); // Known non-null because of need_native_...
493+
if (dataDir == NULL) {
494+
android::PreInitializeNativeBridge(NULL, isa_string.c_str());
495+
} else {
496+
ScopedUtfChars data_dir(env, dataDir);
497+
android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());
498+
}
499+
}
500+
478501
int rc = setresgid(gid, gid, gid);
479502
if (rc == -1) {
480503
ALOGE("setresgid(%d) failed", gid);
@@ -563,7 +586,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
563586
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
564587
jint debug_flags, jobjectArray rlimits,
565588
jint mount_external, jstring se_info, jstring se_name,
566-
jintArray fdsToClose, jstring instructionSet) {
589+
jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
567590
// Grant CAP_WAKE_ALARM to the Bluetooth process.
568591
jlong capabilities = 0;
569592
if (uid == AID_BLUETOOTH) {
@@ -572,7 +595,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
572595

573596
return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
574597
rlimits, capabilities, capabilities, mount_external, se_info,
575-
se_name, false, fdsToClose, instructionSet);
598+
se_name, false, fdsToClose, instructionSet, appDataDir);
576599
}
577600

578601
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
@@ -582,7 +605,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
582605
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
583606
debug_flags, rlimits,
584607
permittedCapabilities, effectiveCapabilities,
585-
MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL, NULL);
608+
MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,
609+
NULL, NULL);
586610
if (pid > 0) {
587611
// The zygote process checks whether the child process has died or not.
588612
ALOGI("System server process %d has been created", pid);
@@ -601,7 +625,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer(
601625

602626
static JNINativeMethod gMethods[] = {
603627
{ "nativeForkAndSpecialize",
604-
"(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;)I",
628+
"(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I",
605629
(void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
606630
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
607631
(void *) com_android_internal_os_Zygote_nativeForkSystemServer }

0 commit comments

Comments
 (0)