2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * dalvik.system.Zygote
21 #include "native/InternalNativePriv.h"
24 #include <selinux/android.h>
28 #include <sys/types.h>
33 #include <sys/personality.h>
35 #include <sys/mount.h>
37 #include <cutils/fs.h>
38 #include <cutils/sched_policy.h>
39 #include <cutils/multiuser.h>
42 #if defined(HAVE_PRCTL)
43 # include <sys/prctl.h>
46 #define ZYGOTE_LOG_TAG "Zygote"
48 /* must match values in dalvik.system.Zygote */
50 DEBUG_ENABLE_DEBUGGER = 1,
51 DEBUG_ENABLE_CHECKJNI = 1 << 1,
52 DEBUG_ENABLE_ASSERT = 1 << 2,
53 DEBUG_ENABLE_SAFEMODE = 1 << 3,
54 DEBUG_ENABLE_JNI_LOGGING = 1 << 4,
57 /* must match values in dalvik.system.Zygote */
59 MOUNT_EXTERNAL_NONE = 0,
60 MOUNT_EXTERNAL_SINGLEUSER = 1,
61 MOUNT_EXTERNAL_MULTIUSER = 2,
65 * This signal handler is for zygote mode, since the zygote
66 * must reap its children
68 static void sigchldHandler(int s)
73 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
74 /* Log process-death status that we care about. In general it is not
75 safe to call ALOG(...) from a signal handler because of possible
76 reentrancy. However, we know a priori that the current implementation
77 of ALOG() is safe to call from a SIGCHLD handler in the zygote process.
78 If the ALOG() implementation changes its locking strategy or its use
79 of syscalls within the lazy-init critical section, its use here may
81 if (WIFEXITED(status)) {
82 if (WEXITSTATUS(status)) {
83 ALOG(LOG_DEBUG, ZYGOTE_LOG_TAG, "Process %d exited cleanly (%d)",
84 (int) pid, WEXITSTATUS(status));
86 IF_ALOGV(/*should use ZYGOTE_LOG_TAG*/) {
87 ALOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
88 "Process %d exited cleanly (%d)",
89 (int) pid, WEXITSTATUS(status));
92 } else if (WIFSIGNALED(status)) {
93 if (WTERMSIG(status) != SIGKILL) {
94 ALOG(LOG_DEBUG, ZYGOTE_LOG_TAG,
95 "Process %d terminated by signal (%d)",
96 (int) pid, WTERMSIG(status));
98 IF_ALOGV(/*should use ZYGOTE_LOG_TAG*/) {
99 ALOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
100 "Process %d terminated by signal (%d)",
101 (int) pid, WTERMSIG(status));
105 if (WCOREDUMP(status)) {
106 ALOG(LOG_INFO, ZYGOTE_LOG_TAG, "Process %d dumped core",
109 #endif /* ifdef WCOREDUMP */
113 * If the just-crashed process is the system_server, bring down zygote
114 * so that it is restarted by init and system server will be restarted
117 if (pid == gDvm.systemServerPid) {
118 ALOG(LOG_INFO, ZYGOTE_LOG_TAG,
119 "Exit zygote because system server (%d) has terminated",
121 kill(getpid(), SIGKILL);
126 ALOG(LOG_WARN, ZYGOTE_LOG_TAG,
127 "Zygote SIGCHLD error in waitpid: %s",strerror(errno));
132 * configure sigchld handler for the zygote process
133 * This is configured very late, because earlier in the dalvik lifecycle
134 * we can fork() and exec() for the verifier/optimizer, and we
135 * want to waitpid() for those rather than have them be harvested immediately.
137 * This ends up being called repeatedly before each fork(), but there's
138 * no real harm in that.
140 static void setSignalHandler()
145 memset(&sa, 0, sizeof(sa));
147 sa.sa_handler = sigchldHandler;
149 err = sigaction (SIGCHLD, &sa, NULL);
152 ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
157 * Set the SIGCHLD handler back to default behavior in zygote children
159 static void unsetSignalHandler()
164 memset(&sa, 0, sizeof(sa));
166 sa.sa_handler = SIG_DFL;
168 err = sigaction (SIGCHLD, &sa, NULL);
171 ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
176 * Calls POSIX setgroups() using the int[] object as an argument.
177 * A NULL argument is tolerated.
180 static int setgroupsIntarray(ArrayObject* gidArray)
186 if (gidArray == NULL) {
190 /* just in case gid_t and u4 are different... */
191 gids = (gid_t *)alloca(sizeof(gid_t) * gidArray->length);
192 contents = (s4 *)(void *)gidArray->contents;
194 for (i = 0 ; i < gidArray->length ; i++) {
195 gids[i] = (gid_t) contents[i];
198 return setgroups((size_t) gidArray->length, gids);
202 * Sets the resource limits via setrlimit(2) for the values in the
203 * two-dimensional array of integers that's passed in. The second dimension
204 * contains a tuple of length 3: (resource, rlim_cur, rlim_max). NULL is
205 * treated as an empty array.
207 * -1 is returned on error.
209 static int setrlimitsFromArray(ArrayObject* rlimits)
214 if (rlimits == NULL) {
218 memset (&rlim, 0, sizeof(rlim));
220 ArrayObject** tuples = (ArrayObject **)(void *)rlimits->contents;
222 for (i = 0; i < rlimits->length; i++) {
223 ArrayObject * rlimit_tuple = tuples[i];
224 s4* contents = (s4 *)(void *)rlimit_tuple->contents;
227 if (rlimit_tuple->length != 3) {
228 ALOGE("rlimits array must have a second dimension of size 3");
232 rlim.rlim_cur = contents[1];
233 rlim.rlim_max = contents[2];
235 err = setrlimit(contents[0], &rlim);
246 * Create private mount space for this process and mount SD card
247 * into it, based on active user. See storage config details at
248 * http://source.android.com/tech/storage/
250 static int mountExternalStorage(uid_t uid, u4 mountExternal) {
251 userid_t userid = multiuser_get_user_id(uid);
253 // Create private mount namespace for our process
254 if (unshare(CLONE_NEWNS) == -1) {
255 SLOGE("Failed to unshare(): %s", strerror(errno));
259 // Mark rootfs as being a slave in our process so that changes
260 // from parent namespace flow into our process.
261 if (mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) == -1) {
262 SLOGE("Failed to mount() rootfs as MS_SLAVE: %s", strerror(errno));
266 // Create bind mounts to expose external storage
267 if (mountExternal == MOUNT_EXTERNAL_MULTIUSER) {
268 const char* storage_base = getenv("ANDROID_STORAGE");
269 const char* target = getenv("EXTERNAL_STORAGE");
270 const char* source_base = getenv("MULTIUSER_EXTERNAL_STORAGE");
271 if (storage_base == NULL || target == NULL || source_base == NULL) {
272 SLOGE("Storage environment undefined; unable to provide external storage");
276 // Give ourselves a tmpfs staging platform to work with, which obscures
277 // any existing shell-specific contents. Create our mount target, then
278 // remount read-only.
279 if (mount("tmpfs", storage_base, "tmpfs", MS_NOSUID | MS_NODEV,
280 "uid=0,gid=1028,mode=0050") == -1) {
281 SLOGE("Failed to mount tmpfs to %s: %s", storage_base, strerror(errno));
284 if (fs_prepare_dir(target, 0000, 0, 0) == -1) {
287 if (mount("tmpfs", storage_base, NULL,
288 MS_REMOUNT | MS_RDONLY | MS_NOSUID | MS_NODEV, NULL)) {
289 SLOGE("Failed to remount ro %s: %s", storage_base, strerror(errno));
293 // Mount our user-specific external storage into place
294 std::string source(StringPrintf("%s/%d", source_base, userid));
295 if (fs_prepare_dir(source.c_str(), 0000, 0, 0) == -1) {
298 if (mount(source.c_str(), target, NULL, MS_BIND, NULL) == -1) {
299 SLOGE("Failed to bind mount %s to %s: %s", source.c_str(), target, strerror(errno));
303 // Mount shared OBB storage into place
304 std::string obb_source(StringPrintf("%s/obb", source_base));
305 std::string android_target(StringPrintf("%s/Android", target));
306 std::string android_obb_target(StringPrintf("%s/Android/obb", target));
307 if (fs_prepare_dir(obb_source.c_str(), 0000, 0, 0) == -1
308 || fs_prepare_dir(android_target.c_str(), 0000, 0, 0) == -1
309 || fs_prepare_dir(android_obb_target.c_str(), 0000, 0, 0) == -1) {
312 if (mount(obb_source.c_str(), android_obb_target.c_str(), NULL, MS_BIND, NULL) == -1) {
313 SLOGE("Failed to bind mount %s to %s: %s",
314 obb_source.c_str(), android_obb_target.c_str(), strerror(errno));
319 SLOGE("Mount mode %d unsupported", mountExternal);
326 /* native public static int fork(); */
327 static void Dalvik_dalvik_system_Zygote_fork(const u4* args, JValue* pResult)
332 dvmThrowIllegalStateException(
333 "VM instance not started with -Xzygote");
338 if (!dvmGcPreZygoteFork()) {
339 ALOGE("pre-fork heap failed");
345 dvmDumpLoaderStats("zygote");
348 #ifdef HAVE_ANDROID_OS
351 extern int gMallocLeakZygoteChild;
352 gMallocLeakZygoteChild = 1;
360 * Enable/disable debug features requested by the caller.
363 * If set, enable debugging; if not set, disable debugging. This is
364 * easy to handle, because the JDWP thread isn't started until we call
365 * dvmInitAfterZygote().
367 * If set, make sure "check JNI" is enabled.
369 * If set, make sure assertions are enabled. This gets fairly weird,
370 * because it affects the result of a method called by class initializers,
371 * and hence can't affect pre-loaded/initialized classes.
373 * If set, operates the VM in the safe mode. The definition of "safe mode" is
374 * implementation dependent and currently only the JIT compiler is disabled.
375 * This is easy to handle because the compiler thread and associated resources
376 * are not requested until we call dvmInitAfterZygote().
378 static void enableDebugFeatures(u4 debugFlags)
380 ALOGV("debugFlags is 0x%02x", debugFlags);
382 gDvm.jdwpAllowed = ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0);
384 if ((debugFlags & DEBUG_ENABLE_CHECKJNI) != 0) {
385 /* turn it on if it's not already enabled */
386 dvmLateEnableCheckedJni();
389 if ((debugFlags & DEBUG_ENABLE_JNI_LOGGING) != 0) {
390 gDvmJni.logThirdPartyJni = true;
393 if ((debugFlags & DEBUG_ENABLE_ASSERT) != 0) {
394 /* turn it on if it's not already enabled */
395 dvmLateEnableAssertions();
398 if ((debugFlags & DEBUG_ENABLE_SAFEMODE) != 0) {
399 #if defined(WITH_JIT)
400 /* turn off the jit if it is explicitly requested by the app */
401 if (gDvm.executionMode == kExecutionModeJit)
402 gDvm.executionMode = kExecutionModeInterpFast;
406 #ifdef HAVE_ANDROID_OS
407 if ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0) {
408 /* To let a non-privileged gdbserver attach to this
409 * process, we must set its dumpable bit flag. However
410 * we are not interested in generating a coredump in
411 * case of a crash, so also set the coredump size to 0
414 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
415 ALOGE("could not set dumpable bit flag for pid %d: %s",
416 getpid(), strerror(errno));
420 rl.rlim_max = RLIM_INFINITY;
421 if (setrlimit(RLIMIT_CORE, &rl) < 0) {
422 ALOGE("could not disable core file generation for pid %d: %s",
423 getpid(), strerror(errno));
431 * Set Linux capability flags.
433 * Returns 0 on success, errno on failure.
435 static int setCapabilities(int64_t permitted, int64_t effective)
437 #ifdef HAVE_ANDROID_OS
438 struct __user_cap_header_struct capheader;
439 struct __user_cap_data_struct capdata;
441 memset(&capheader, 0, sizeof(capheader));
442 memset(&capdata, 0, sizeof(capdata));
444 capheader.version = _LINUX_CAPABILITY_VERSION;
447 capdata.effective = effective;
448 capdata.permitted = permitted;
450 ALOGV("CAPSET perm=%llx eff=%llx", permitted, effective);
451 if (capset(&capheader, &capdata) != 0)
453 #endif /*HAVE_ANDROID_OS*/
460 * Set SELinux security context.
462 * Returns 0 on success, -1 on failure.
464 static int setSELinuxContext(uid_t uid, bool isSystemServer,
465 const char *seInfo, const char *niceName)
467 #ifdef HAVE_ANDROID_OS
468 return selinux_android_setcontext(uid, isSystemServer, seInfo, niceName);
476 * Utility routine to fork zygote and specialize the child process.
478 static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
482 uid_t uid = (uid_t) args[0];
483 gid_t gid = (gid_t) args[1];
484 ArrayObject* gids = (ArrayObject *)args[2];
485 u4 debugFlags = args[3];
486 ArrayObject *rlimits = (ArrayObject *)args[4];
487 u4 mountExternal = MOUNT_EXTERNAL_NONE;
488 int64_t permittedCapabilities, effectiveCapabilities;
491 char *niceName = NULL;
494 if (isSystemServer) {
496 * Don't use GET_ARG_LONG here for now. gcc is generating code
497 * that uses register d8 as a temporary, and that's coming out
498 * scrambled in the child process. b/3138621
500 //permittedCapabilities = GET_ARG_LONG(args, 5);
501 //effectiveCapabilities = GET_ARG_LONG(args, 7);
502 permittedCapabilities = args[5] | (int64_t) args[6] << 32;
503 effectiveCapabilities = args[7] | (int64_t) args[8] << 32;
505 mountExternal = args[5];
506 permittedCapabilities = effectiveCapabilities = 0;
508 StringObject* seInfoObj = (StringObject*)args[6];
510 seInfo = dvmCreateCstrFromString(seInfoObj);
512 ALOGE("seInfo dvmCreateCstrFromString failed");
516 StringObject* niceNameObj = (StringObject*)args[7];
518 niceName = dvmCreateCstrFromString(niceNameObj);
520 ALOGE("niceName dvmCreateCstrFromString failed");
528 dvmThrowIllegalStateException(
529 "VM instance not started with -Xzygote");
534 if (!dvmGcPreZygoteFork()) {
535 ALOGE("pre-fork heap failed");
541 dvmDumpLoaderStats("zygote");
546 /* The child process */
548 #ifdef HAVE_ANDROID_OS
549 extern int gMallocLeakZygoteChild;
550 gMallocLeakZygoteChild = 1;
552 /* keep caps across UID change, unless we're staying root */
554 err = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
557 ALOGE("cannot PR_SET_KEEPCAPS: %s", strerror(errno));
562 #endif /* HAVE_ANDROID_OS */
564 if (mountExternal != MOUNT_EXTERNAL_NONE) {
565 err = mountExternalStorage(uid, mountExternal);
567 ALOGE("cannot mountExternalStorage(): %s", strerror(errno));
569 if (errno == ENOTCONN || errno == EROFS) {
570 // When device is actively encrypting, we get ENOTCONN here
571 // since FUSE was mounted before the framework restarted.
572 // When encrypted device is booting, we get EROFS since
573 // FUSE hasn't been created yet by init.
574 // In either case, continue without external storage.
581 err = setgroupsIntarray(gids);
583 ALOGE("cannot setgroups(): %s", strerror(errno));
587 err = setrlimitsFromArray(rlimits);
589 ALOGE("cannot setrlimit(): %s", strerror(errno));
595 ALOGE("cannot setgid(%d): %s", gid, strerror(errno));
601 ALOGE("cannot setuid(%d): %s", uid, strerror(errno));
605 int current = personality(0xffffFFFF);
606 int success = personality((ADDR_NO_RANDOMIZE | current));
608 ALOGW("Personality switch failed. current=%d error=%d\n", current, errno);
611 err = setCapabilities(permittedCapabilities, effectiveCapabilities);
613 ALOGE("cannot set capabilities (%llx,%llx): %s",
614 permittedCapabilities, effectiveCapabilities, strerror(err));
618 err = set_sched_policy(0, SP_DEFAULT);
620 ALOGE("cannot set_sched_policy(0, SP_DEFAULT): %s", strerror(-err));
625 err = setSELinuxContext(uid, isSystemServer, seInfo, niceName);
627 ALOGE("cannot set SELinux context: %s\n", strerror(errno));
630 // These free(3) calls are safe because we know we're only ever forking
631 // a single-threaded process, so we know no other thread held the heap
632 // lock when we forked.
638 * Our system thread ID has changed. Get the new one.
640 Thread* thread = dvmThreadSelf();
641 thread->systemTid = dvmGetSysThreadId();
643 /* configure additional debug options */
644 enableDebugFeatures(debugFlags);
646 unsetSignalHandler();
648 if (!dvmInitAfterZygote()) {
649 ALOGE("error in post-zygote initialization");
652 } else if (pid > 0) {
653 /* the parent process */
664 * native public static int nativeForkAndSpecialize(int uid, int gid,
665 * int[] gids, int debugFlags, int[][] rlimits, int mountExternal,
666 * String seInfo, String niceName);
668 static void Dalvik_dalvik_system_Zygote_forkAndSpecialize(const u4* args,
673 pid = forkAndSpecializeCommon(args, false);
679 * native public static int nativeForkSystemServer(int uid, int gid,
680 * int[] gids, int debugFlags, int[][] rlimits,
681 * long permittedCapabilities, long effectiveCapabilities);
683 static void Dalvik_dalvik_system_Zygote_forkSystemServer(
684 const u4* args, JValue* pResult)
687 pid = forkAndSpecializeCommon(args, true);
689 /* The zygote process checks whether the child process has died or not. */
693 ALOGI("System server process %d has been created", pid);
694 gDvm.systemServerPid = pid;
695 /* There is a slight window that the system server process has crashed
696 * but it went unnoticed because we haven't published its pid yet. So
697 * we recheck here just to make sure that all is well.
699 if (waitpid(pid, &status, WNOHANG) == pid) {
700 ALOGE("System server process %d has died. Restarting Zygote!", pid);
701 kill(getpid(), SIGKILL);
707 /* native private static void nativeExecShell(String command);
709 static void Dalvik_dalvik_system_Zygote_execShell(
710 const u4* args, JValue* pResult)
712 StringObject* command = (StringObject*)args[0];
714 const char *argp[] = {_PATH_BSHELL, "-c", NULL, NULL};
715 argp[2] = dvmCreateCstrFromString(command);
717 ALOGI("Exec: %s %s %s", argp[0], argp[1], argp[2]);
719 execv(_PATH_BSHELL, (char**)argp);
723 const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {
724 { "nativeFork", "()I",
725 Dalvik_dalvik_system_Zygote_fork },
726 { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;)I",
727 Dalvik_dalvik_system_Zygote_forkAndSpecialize },
728 { "nativeForkSystemServer", "(II[II[[IJJ)I",
729 Dalvik_dalvik_system_Zygote_forkSystemServer },
730 { "nativeExecShell", "(Ljava/lang/String;)V",
731 Dalvik_dalvik_system_Zygote_execShell },
732 { NULL, NULL, NULL },