OSDN Git Service

Backport changes to whitelist sockets opened by the zygote.
[android-x86/frameworks-base.git] / core / jni / com_android_internal_os_Zygote.cpp
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #define LOG_TAG "Zygote"
18
19 #include <sstream>
20
21 // sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc
22 #include <sys/mount.h>
23 #include <linux/fs.h>
24
25 #include <list>
26 #include <string>
27
28 #include <fcntl.h>
29 #include <grp.h>
30 #include <inttypes.h>
31 #include <mntent.h>
32 #include <paths.h>
33 #include <signal.h>
34 #include <stdlib.h>
35 #include <sys/capability.h>
36 #include <sys/personality.h>
37 #include <sys/prctl.h>
38 #include <sys/resource.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <sys/utsname.h>
42 #include <sys/wait.h>
43 #include <unistd.h>
44
45 #include <cutils/fs.h>
46 #include <cutils/multiuser.h>
47 #include <cutils/sched_policy.h>
48 #include <private/android_filesystem_config.h>
49 #include <utils/String8.h>
50 #include <selinux/android.h>
51 #include <processgroup/processgroup.h>
52
53 #include "core_jni_helpers.h"
54 #include "JNIHelp.h"
55 #include "ScopedLocalRef.h"
56 #include "ScopedPrimitiveArray.h"
57 #include "ScopedUtfChars.h"
58 #include "fd_utils-inl.h"
59
60 #include "nativebridge/native_bridge.h"
61
62 namespace {
63
64 using android::String8;
65
66 static pid_t gSystemServerPid = 0;
67
68 static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
69 static jclass gZygoteClass;
70 static jmethodID gCallPostForkChildHooks;
71
72 // Must match values in com.android.internal.os.Zygote.
73 enum MountExternalKind {
74   MOUNT_EXTERNAL_NONE = 0,
75   MOUNT_EXTERNAL_DEFAULT = 1,
76   MOUNT_EXTERNAL_READ = 2,
77   MOUNT_EXTERNAL_WRITE = 3,
78 };
79
80 static void RuntimeAbort(JNIEnv* env) {
81   env->FatalError("RuntimeAbort");
82 }
83
84 static void RuntimeAbort(JNIEnv* env, int line, const char* msg) {
85   std::ostringstream oss;
86   oss << __FILE__ << ":" << line << ": " << msg;
87   env->FatalError(oss.str().c_str());
88 }
89
90 // This signal handler is for zygote mode, since the zygote must reap its children
91 static void SigChldHandler(int /*signal_number*/) {
92   pid_t pid;
93   int status;
94
95   // It's necessary to save and restore the errno during this function.
96   // Since errno is stored per thread, changing it here modifies the errno
97   // on the thread on which this signal handler executes. If a signal occurs
98   // between a call and an errno check, it's possible to get the errno set
99   // here.
100   // See b/23572286 for extra information.
101   int saved_errno = errno;
102
103   while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
104      // Log process-death status that we care about.  In general it is
105      // not safe to call LOG(...) from a signal handler because of
106      // possible reentrancy.  However, we know a priori that the
107      // current implementation of LOG() is safe to call from a SIGCHLD
108      // handler in the zygote process.  If the LOG() implementation
109      // changes its locking strategy or its use of syscalls within the
110      // lazy-init critical section, its use here may become unsafe.
111     if (WIFEXITED(status)) {
112       if (WEXITSTATUS(status)) {
113         ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
114       }
115     } else if (WIFSIGNALED(status)) {
116       if (WTERMSIG(status) != SIGKILL) {
117         ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
118       }
119       if (WCOREDUMP(status)) {
120         ALOGI("Process %d dumped core.", pid);
121       }
122     }
123
124     // If the just-crashed process is the system_server, bring down zygote
125     // so that it is restarted by init and system server will be restarted
126     // from there.
127     if (pid == gSystemServerPid) {
128       ALOGE("Exit zygote because system server (%d) has terminated", pid);
129       kill(getpid(), SIGKILL);
130     }
131   }
132
133   // Note that we shouldn't consider ECHILD an error because
134   // the secondary zygote might have no children left to wait for.
135   if (pid < 0 && errno != ECHILD) {
136     ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
137   }
138
139   errno = saved_errno;
140 }
141
142 // Configures the SIGCHLD handler for the zygote process. This is configured
143 // very late, because earlier in the runtime we may fork() and exec()
144 // other processes, and we want to waitpid() for those rather than
145 // have them be harvested immediately.
146 //
147 // This ends up being called repeatedly before each fork(), but there's
148 // no real harm in that.
149 static void SetSigChldHandler() {
150   struct sigaction sa;
151   memset(&sa, 0, sizeof(sa));
152   sa.sa_handler = SigChldHandler;
153
154   int err = sigaction(SIGCHLD, &sa, NULL);
155   if (err < 0) {
156     ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
157   }
158 }
159
160 // Sets the SIGCHLD handler back to default behavior in zygote children.
161 static void UnsetSigChldHandler() {
162   struct sigaction sa;
163   memset(&sa, 0, sizeof(sa));
164   sa.sa_handler = SIG_DFL;
165
166   int err = sigaction(SIGCHLD, &sa, NULL);
167   if (err < 0) {
168     ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
169   }
170 }
171
172 // Calls POSIX setgroups() using the int[] object as an argument.
173 // A NULL argument is tolerated.
174 static void SetGids(JNIEnv* env, jintArray javaGids) {
175   if (javaGids == NULL) {
176     return;
177   }
178
179   ScopedIntArrayRO gids(env, javaGids);
180   if (gids.get() == NULL) {
181       RuntimeAbort(env);
182   }
183   int rc = setgroups(gids.size(), reinterpret_cast<const gid_t*>(&gids[0]));
184   if (rc == -1) {
185     ALOGE("setgroups failed");
186     RuntimeAbort(env);
187   }
188 }
189
190 // Sets the resource limits via setrlimit(2) for the values in the
191 // two-dimensional array of integers that's passed in. The second dimension
192 // contains a tuple of length 3: (resource, rlim_cur, rlim_max). NULL is
193 // treated as an empty array.
194 static void SetRLimits(JNIEnv* env, jobjectArray javaRlimits) {
195   if (javaRlimits == NULL) {
196     return;
197   }
198
199   rlimit rlim;
200   memset(&rlim, 0, sizeof(rlim));
201
202   for (int i = 0; i < env->GetArrayLength(javaRlimits); ++i) {
203     ScopedLocalRef<jobject> javaRlimitObject(env, env->GetObjectArrayElement(javaRlimits, i));
204     ScopedIntArrayRO javaRlimit(env, reinterpret_cast<jintArray>(javaRlimitObject.get()));
205     if (javaRlimit.size() != 3) {
206       ALOGE("rlimits array must have a second dimension of size 3");
207       RuntimeAbort(env);
208     }
209
210     rlim.rlim_cur = javaRlimit[1];
211     rlim.rlim_max = javaRlimit[2];
212
213     int rc = setrlimit(javaRlimit[0], &rlim);
214     if (rc == -1) {
215       ALOGE("setrlimit(%d, {%ld, %ld}) failed", javaRlimit[0], rlim.rlim_cur,
216             rlim.rlim_max);
217       RuntimeAbort(env);
218     }
219   }
220 }
221
222 // The debug malloc library needs to know whether it's the zygote or a child.
223 extern "C" int gMallocLeakZygoteChild;
224
225 static void EnableKeepCapabilities(JNIEnv* env) {
226   int rc = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
227   if (rc == -1) {
228     ALOGE("prctl(PR_SET_KEEPCAPS) failed");
229     RuntimeAbort(env);
230   }
231 }
232
233 static void DropCapabilitiesBoundingSet(JNIEnv* env) {
234   for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
235     int rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
236     if (rc == -1) {
237       if (errno == EINVAL) {
238         ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
239               "your kernel is compiled with file capabilities support");
240       } else {
241         ALOGE("prctl(PR_CAPBSET_DROP) failed");
242         RuntimeAbort(env);
243       }
244     }
245   }
246 }
247
248 static void SetCapabilities(JNIEnv* env, int64_t permitted, int64_t effective) {
249   __user_cap_header_struct capheader;
250   memset(&capheader, 0, sizeof(capheader));
251   capheader.version = _LINUX_CAPABILITY_VERSION_3;
252   capheader.pid = 0;
253
254   __user_cap_data_struct capdata[2];
255   memset(&capdata, 0, sizeof(capdata));
256   capdata[0].effective = effective;
257   capdata[1].effective = effective >> 32;
258   capdata[0].permitted = permitted;
259   capdata[1].permitted = permitted >> 32;
260
261   if (capset(&capheader, &capdata[0]) == -1) {
262     ALOGE("capset(%" PRId64 ", %" PRId64 ") failed", permitted, effective);
263     RuntimeAbort(env);
264   }
265 }
266
267 static void SetSchedulerPolicy(JNIEnv* env) {
268   errno = -set_sched_policy(0, SP_DEFAULT);
269   if (errno != 0) {
270     ALOGE("set_sched_policy(0, SP_DEFAULT) failed");
271     RuntimeAbort(env);
272   }
273 }
274
275 static int UnmountTree(const char* path) {
276     size_t path_len = strlen(path);
277
278     FILE* fp = setmntent("/proc/mounts", "r");
279     if (fp == NULL) {
280         ALOGE("Error opening /proc/mounts: %s", strerror(errno));
281         return -errno;
282     }
283
284     // Some volumes can be stacked on each other, so force unmount in
285     // reverse order to give us the best chance of success.
286     std::list<std::string> toUnmount;
287     mntent* mentry;
288     while ((mentry = getmntent(fp)) != NULL) {
289         if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
290             toUnmount.push_front(std::string(mentry->mnt_dir));
291         }
292     }
293     endmntent(fp);
294
295     for (auto path : toUnmount) {
296         if (umount2(path.c_str(), MNT_DETACH)) {
297             ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
298         }
299     }
300     return 0;
301 }
302
303 // Create a private mount namespace and bind mount appropriate emulated
304 // storage for the given user.
305 static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
306         bool force_mount_namespace) {
307     // See storage config details at http://source.android.com/tech/storage/
308
309     // Create a second private mount namespace for our process
310     if (unshare(CLONE_NEWNS) == -1) {
311         ALOGW("Failed to unshare(): %s", strerror(errno));
312         return false;
313     }
314
315     // Unmount storage provided by root namespace and mount requested view
316     UnmountTree("/storage");
317
318     String8 storageSource;
319     if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
320         storageSource = "/mnt/runtime/default";
321     } else if (mount_mode == MOUNT_EXTERNAL_READ) {
322         storageSource = "/mnt/runtime/read";
323     } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
324         storageSource = "/mnt/runtime/write";
325     } else {
326         // Sane default of no storage visible
327         return true;
328     }
329     if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
330             NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
331         ALOGW("Failed to mount %s to /storage: %s", storageSource.string(), strerror(errno));
332         return false;
333     }
334
335     // Mount user-specific symlink helper into place
336     userid_t user_id = multiuser_get_user_id(uid);
337     const String8 userSource(String8::format("/mnt/user/%d", user_id));
338     if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
339         return false;
340     }
341     if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
342             NULL, MS_BIND, NULL)) == -1) {
343         ALOGW("Failed to mount %s to /storage/self: %s", userSource.string(), strerror(errno));
344         return false;
345     }
346
347     return true;
348 }
349
350 static bool NeedsNoRandomizeWorkaround() {
351 #if !defined(__arm__)
352     return false;
353 #else
354     int major;
355     int minor;
356     struct utsname uts;
357     if (uname(&uts) == -1) {
358         return false;
359     }
360
361     if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
362         return false;
363     }
364
365     // Kernels before 3.4.* need the workaround.
366     return (major < 3) || ((major == 3) && (minor < 4));
367 #endif
368 }
369
370 // Utility to close down the Zygote socket file descriptors while
371 // the child is still running as root with Zygote's privileges.  Each
372 // descriptor (if any) is closed via dup2(), replacing it with a valid
373 // (open) descriptor to /dev/null.
374
375 static void DetachDescriptors(JNIEnv* env, jintArray fdsToClose) {
376   if (!fdsToClose) {
377     return;
378   }
379   jsize count = env->GetArrayLength(fdsToClose);
380   jint *ar = env->GetIntArrayElements(fdsToClose, 0);
381   if (!ar) {
382       ALOGE("Bad fd array");
383       RuntimeAbort(env);
384   }
385   jsize i;
386   int devnull;
387   for (i = 0; i < count; i++) {
388     devnull = open("/dev/null", O_RDWR);
389     if (devnull < 0) {
390       ALOGE("Failed to open /dev/null: %s", strerror(errno));
391       RuntimeAbort(env);
392       continue;
393     }
394     ALOGV("Switching descriptor %d to /dev/null: %s", ar[i], strerror(errno));
395     if (dup2(devnull, ar[i]) < 0) {
396       ALOGE("Failed dup2() on descriptor %d: %s", ar[i], strerror(errno));
397       RuntimeAbort(env);
398     }
399     close(devnull);
400   }
401 }
402
403 void SetThreadName(const char* thread_name) {
404   bool hasAt = false;
405   bool hasDot = false;
406   const char* s = thread_name;
407   while (*s) {
408     if (*s == '.') {
409       hasDot = true;
410     } else if (*s == '@') {
411       hasAt = true;
412     }
413     s++;
414   }
415   const int len = s - thread_name;
416   if (len < 15 || hasAt || !hasDot) {
417     s = thread_name;
418   } else {
419     s = thread_name + len - 15;
420   }
421   // pthread_setname_np fails rather than truncating long strings.
422   char buf[16];       // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
423   strlcpy(buf, s, sizeof(buf)-1);
424   errno = pthread_setname_np(pthread_self(), buf);
425   if (errno != 0) {
426     ALOGW("Unable to set the name of current thread to '%s': %s", buf, strerror(errno));
427   }
428 }
429
430 #ifdef ENABLE_SCHED_BOOST
431 static void SetForkLoad(bool boost) {
432   // set scheduler knob to boost forked processes
433   pid_t currentPid = getpid();
434   // fits at most "/proc/XXXXXXX/sched_init_task_load\0"
435   char schedPath[35];
436   snprintf(schedPath, sizeof(schedPath), "/proc/%u/sched_init_task_load", currentPid);
437   int schedBoostFile = open(schedPath, O_WRONLY);
438   if (schedBoostFile < 0) {
439     ALOGW("Unable to set zygote scheduler boost");
440     return;
441   }
442   if (boost) {
443     write(schedBoostFile, "100\0", 4);
444   } else {
445     write(schedBoostFile, "0\0", 2);
446   }
447   close(schedBoostFile);
448 }
449 #endif
450
451 // The list of open zygote file descriptors.
452 static FileDescriptorTable* gOpenFdTable = NULL;
453
454 // Utility routine to fork zygote and specialize the child process.
455 static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
456                                      jint debug_flags, jobjectArray javaRlimits,
457                                      jlong permittedCapabilities, jlong effectiveCapabilities,
458                                      jint mount_external,
459                                      jstring java_se_info, jstring java_se_name,
460                                      bool is_system_server, jintArray fdsToClose,
461                                      jstring instructionSet, jstring dataDir) {
462   SetSigChldHandler();
463
464 #ifdef ENABLE_SCHED_BOOST
465   SetForkLoad(true);
466 #endif
467
468   // Close any logging related FDs before we start evaluating the list of
469   // file descriptors.
470   __android_log_close();
471
472   // If this is the first fork for this zygote, create the open FD table.
473   // If it isn't, we just need to check whether the list of open files has
474   // changed (and it shouldn't in the normal case).
475   if (gOpenFdTable == NULL) {
476     gOpenFdTable = FileDescriptorTable::Create();
477     if (gOpenFdTable == NULL) {
478       RuntimeAbort(env, __LINE__, "Unable to construct file descriptor table.");
479     }
480   } else if (!gOpenFdTable->Restat()) {
481     RuntimeAbort(env, __LINE__, "Unable to restat file descriptor table.");
482   }
483
484   pid_t pid = fork();
485
486   if (pid == 0) {
487     // The child process.
488     gMallocLeakZygoteChild = 1;
489
490     // Clean up any descriptors which must be closed immediately
491     DetachDescriptors(env, fdsToClose);
492
493     // Re-open all remaining open file descriptors so that they aren't shared
494     // with the zygote across a fork.
495     if (!gOpenFdTable->ReopenOrDetach()) {
496       RuntimeAbort(env, __LINE__, "Unable to reopen whitelisted descriptors.");
497     }
498
499     // Keep capabilities across UID change, unless we're staying root.
500     if (uid != 0) {
501       EnableKeepCapabilities(env);
502     }
503
504     DropCapabilitiesBoundingSet(env);
505
506     bool use_native_bridge = !is_system_server && (instructionSet != NULL)
507         && android::NativeBridgeAvailable();
508     if (use_native_bridge) {
509       ScopedUtfChars isa_string(env, instructionSet);
510       use_native_bridge = android::NeedsNativeBridge(isa_string.c_str());
511     }
512     if (use_native_bridge && dataDir == NULL) {
513       // dataDir should never be null if we need to use a native bridge.
514       // In general, dataDir will never be null for normal applications. It can only happen in
515       // special cases (for isolated processes which are not associated with any app). These are
516       // launched by the framework and should not be emulated anyway.
517       use_native_bridge = false;
518       ALOGW("Native bridge will not be used because dataDir == NULL.");
519     }
520
521     if (!MountEmulatedStorage(uid, mount_external, use_native_bridge)) {
522       ALOGW("Failed to mount emulated storage: %s", strerror(errno));
523       if (errno == ENOTCONN || errno == EROFS) {
524         // When device is actively encrypting, we get ENOTCONN here
525         // since FUSE was mounted before the framework restarted.
526         // When encrypted device is booting, we get EROFS since
527         // FUSE hasn't been created yet by init.
528         // In either case, continue without external storage.
529       } else {
530         ALOGE("Cannot continue without emulated storage");
531         RuntimeAbort(env);
532       }
533     }
534
535     if (!is_system_server) {
536         int rc = createProcessGroup(uid, getpid());
537         if (rc != 0) {
538             if (rc == -EROFS) {
539                 ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
540             } else {
541                 ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));
542             }
543         }
544     }
545
546     SetGids(env, javaGids);
547
548     SetRLimits(env, javaRlimits);
549
550     if (use_native_bridge) {
551       ScopedUtfChars isa_string(env, instructionSet);
552       ScopedUtfChars data_dir(env, dataDir);
553       android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());
554     }
555
556     int rc = setresgid(gid, gid, gid);
557     if (rc == -1) {
558       ALOGE("setresgid(%d) failed: %s", gid, strerror(errno));
559       RuntimeAbort(env);
560     }
561
562     rc = setresuid(uid, uid, uid);
563     if (rc == -1) {
564       ALOGE("setresuid(%d) failed: %s", uid, strerror(errno));
565       RuntimeAbort(env);
566     }
567
568     if (NeedsNoRandomizeWorkaround()) {
569         // Work around ARM kernel ASLR lossage (http://b/5817320).
570         int old_personality = personality(0xffffffff);
571         int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
572         if (new_personality == -1) {
573             ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
574         }
575     }
576
577     SetCapabilities(env, permittedCapabilities, effectiveCapabilities);
578
579     SetSchedulerPolicy(env);
580
581     const char* se_info_c_str = NULL;
582     ScopedUtfChars* se_info = NULL;
583     if (java_se_info != NULL) {
584         se_info = new ScopedUtfChars(env, java_se_info);
585         se_info_c_str = se_info->c_str();
586         if (se_info_c_str == NULL) {
587           ALOGE("se_info_c_str == NULL");
588           RuntimeAbort(env);
589         }
590     }
591     const char* se_name_c_str = NULL;
592     ScopedUtfChars* se_name = NULL;
593     if (java_se_name != NULL) {
594         se_name = new ScopedUtfChars(env, java_se_name);
595         se_name_c_str = se_name->c_str();
596         if (se_name_c_str == NULL) {
597           ALOGE("se_name_c_str == NULL");
598           RuntimeAbort(env);
599         }
600     }
601     rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
602     if (rc == -1) {
603       ALOGE("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
604             is_system_server, se_info_c_str, se_name_c_str);
605       RuntimeAbort(env);
606     }
607
608     // Make it easier to debug audit logs by setting the main thread's name to the
609     // nice name rather than "app_process".
610     if (se_info_c_str == NULL && is_system_server) {
611       se_name_c_str = "system_server";
612     }
613     if (se_info_c_str != NULL) {
614       SetThreadName(se_name_c_str);
615     }
616
617     delete se_info;
618     delete se_name;
619
620     UnsetSigChldHandler();
621
622     env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
623                               is_system_server ? NULL : instructionSet);
624     if (env->ExceptionCheck()) {
625       ALOGE("Error calling post fork hooks.");
626       RuntimeAbort(env);
627     }
628   } else if (pid > 0) {
629     // the parent process
630
631 #ifdef ENABLE_SCHED_BOOST
632     // unset scheduler knob
633     SetForkLoad(false);
634 #endif
635
636   }
637   return pid;
638 }
639 }  // anonymous namespace
640
641 namespace android {
642
643 static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
644         JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
645         jint debug_flags, jobjectArray rlimits,
646         jint mount_external, jstring se_info, jstring se_name,
647         jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
648     // Grant CAP_WAKE_ALARM to the Bluetooth process.
649     jlong capabilities = 0;
650     if (uid == AID_BLUETOOTH) {
651         capabilities |= (1LL << CAP_WAKE_ALARM);
652     }
653
654     return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
655             rlimits, capabilities, capabilities, mount_external, se_info,
656             se_name, false, fdsToClose, instructionSet, appDataDir);
657 }
658
659 static jint com_android_internal_os_Zygote_nativeForkSystemServer(
660         JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
661         jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
662         jlong effectiveCapabilities) {
663   pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
664                                       debug_flags, rlimits,
665                                       permittedCapabilities, effectiveCapabilities,
666                                       MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
667                                       NULL, NULL);
668   if (pid > 0) {
669       // The zygote process checks whether the child process has died or not.
670       ALOGI("System server process %d has been created", pid);
671       gSystemServerPid = pid;
672       // There is a slight window that the system server process has crashed
673       // but it went unnoticed because we haven't published its pid yet. So
674       // we recheck here just to make sure that all is well.
675       int status;
676       if (waitpid(pid, &status, WNOHANG) == pid) {
677           ALOGE("System server process %d has died. Restarting Zygote!", pid);
678           RuntimeAbort(env);
679       }
680   }
681   return pid;
682 }
683
684 static JNINativeMethod gMethods[] = {
685     { "nativeForkAndSpecialize",
686       "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I",
687       (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
688     { "nativeForkSystemServer", "(II[II[[IJJ)I",
689       (void *) com_android_internal_os_Zygote_nativeForkSystemServer }
690 };
691
692 int register_com_android_internal_os_Zygote(JNIEnv* env) {
693   gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
694   gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
695                                                    "(ILjava/lang/String;)V");
696
697   return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
698 }
699 }  // namespace android
700