Home | History | Annotate | Download | only in native
      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 /*
     18  * dalvik.system.Zygote
     19  */
     20 #include "Dalvik.h"
     21 #include "native/InternalNativePriv.h"
     22 
     23 #include <selinux/android.h>
     24 
     25 #include <signal.h>
     26 #include <sys/types.h>
     27 #include <sys/wait.h>
     28 #include <grp.h>
     29 #include <errno.h>
     30 #include <paths.h>
     31 #include <sys/personality.h>
     32 #include <sys/stat.h>
     33 #include <sys/mount.h>
     34 #include <linux/fs.h>
     35 #include <cutils/fs.h>
     36 #include <cutils/sched_policy.h>
     37 #include <cutils/multiuser.h>
     38 #include <sched.h>
     39 #include <sys/utsname.h>
     40 #include <sys/capability.h>
     41 
     42 #if defined(HAVE_PRCTL)
     43 # include <sys/prctl.h>
     44 #endif
     45 
     46 #define ZYGOTE_LOG_TAG "Zygote"
     47 
     48 /* must match values in dalvik.system.Zygote */
     49 enum {
     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,
     55 };
     56 
     57 /* must match values in dalvik.system.Zygote */
     58 enum {
     59     MOUNT_EXTERNAL_NONE = 0,
     60     MOUNT_EXTERNAL_SINGLEUSER = 1,
     61     MOUNT_EXTERNAL_MULTIUSER = 2,
     62     MOUNT_EXTERNAL_MULTIUSER_ALL = 3,
     63 };
     64 
     65 /*
     66  * This signal handler is for zygote mode, since the zygote
     67  * must reap its children
     68  */
     69 static void sigchldHandler(int s)
     70 {
     71     pid_t pid;
     72     int status;
     73 
     74     while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
     75         /* Log process-death status that we care about.  In general it is not
     76            safe to call ALOG(...) from a signal handler because of possible
     77            reentrancy.  However, we know a priori that the current implementation
     78            of ALOG() is safe to call from a SIGCHLD handler in the zygote process.
     79            If the ALOG() implementation changes its locking strategy or its use
     80            of syscalls within the lazy-init critical section, its use here may
     81            become unsafe. */
     82         if (WIFEXITED(status)) {
     83             if (WEXITSTATUS(status)) {
     84                 ALOG(LOG_DEBUG, ZYGOTE_LOG_TAG, "Process %d exited cleanly (%d)",
     85                     (int) pid, WEXITSTATUS(status));
     86             } else {
     87                 IF_ALOGV(/*should use ZYGOTE_LOG_TAG*/) {
     88                     ALOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
     89                         "Process %d exited cleanly (%d)",
     90                         (int) pid, WEXITSTATUS(status));
     91                 }
     92             }
     93         } else if (WIFSIGNALED(status)) {
     94             if (WTERMSIG(status) != SIGKILL) {
     95                 ALOG(LOG_DEBUG, ZYGOTE_LOG_TAG,
     96                     "Process %d terminated by signal (%d)",
     97                     (int) pid, WTERMSIG(status));
     98             } else {
     99                 IF_ALOGV(/*should use ZYGOTE_LOG_TAG*/) {
    100                     ALOG(LOG_VERBOSE, ZYGOTE_LOG_TAG,
    101                         "Process %d terminated by signal (%d)",
    102                         (int) pid, WTERMSIG(status));
    103                 }
    104             }
    105 #ifdef WCOREDUMP
    106             if (WCOREDUMP(status)) {
    107                 ALOG(LOG_INFO, ZYGOTE_LOG_TAG, "Process %d dumped core",
    108                     (int) pid);
    109             }
    110 #endif /* ifdef WCOREDUMP */
    111         }
    112 
    113         /*
    114          * If the just-crashed process is the system_server, bring down zygote
    115          * so that it is restarted by init and system server will be restarted
    116          * from there.
    117          */
    118         if (pid == gDvm.systemServerPid) {
    119             ALOG(LOG_INFO, ZYGOTE_LOG_TAG,
    120                 "Exit zygote because system server (%d) has terminated",
    121                 (int) pid);
    122             kill(getpid(), SIGKILL);
    123         }
    124     }
    125 
    126     if (pid < 0) {
    127         ALOG(LOG_WARN, ZYGOTE_LOG_TAG,
    128             "Zygote SIGCHLD error in waitpid: %s",strerror(errno));
    129     }
    130 }
    131 
    132 /*
    133  * configure sigchld handler for the zygote process
    134  * This is configured very late, because earlier in the dalvik lifecycle
    135  * we can fork() and exec() for the verifier/optimizer, and we
    136  * want to waitpid() for those rather than have them be harvested immediately.
    137  *
    138  * This ends up being called repeatedly before each fork(), but there's
    139  * no real harm in that.
    140  */
    141 static void setSignalHandler()
    142 {
    143     int err;
    144     struct sigaction sa;
    145 
    146     memset(&sa, 0, sizeof(sa));
    147 
    148     sa.sa_handler = sigchldHandler;
    149 
    150     err = sigaction (SIGCHLD, &sa, NULL);
    151 
    152     if (err < 0) {
    153         ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
    154     }
    155 }
    156 
    157 /*
    158  * Set the SIGCHLD handler back to default behavior in zygote children
    159  */
    160 static void unsetSignalHandler()
    161 {
    162     int err;
    163     struct sigaction sa;
    164 
    165     memset(&sa, 0, sizeof(sa));
    166 
    167     sa.sa_handler = SIG_DFL;
    168 
    169     err = sigaction (SIGCHLD, &sa, NULL);
    170 
    171     if (err < 0) {
    172         ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
    173     }
    174 }
    175 
    176 /*
    177  * Calls POSIX setgroups() using the int[] object as an argument.
    178  * A NULL argument is tolerated.
    179  */
    180 
    181 static int setgroupsIntarray(ArrayObject* gidArray)
    182 {
    183     gid_t *gids;
    184     u4 i;
    185     s4 *contents;
    186 
    187     if (gidArray == NULL) {
    188         return 0;
    189     }
    190 
    191     /* just in case gid_t and u4 are different... */
    192     gids = (gid_t *)alloca(sizeof(gid_t) * gidArray->length);
    193     contents = (s4 *)(void *)gidArray->contents;
    194 
    195     for (i = 0 ; i < gidArray->length ; i++) {
    196         gids[i] = (gid_t) contents[i];
    197     }
    198 
    199     return setgroups((size_t) gidArray->length, gids);
    200 }
    201 
    202 /*
    203  * Sets the resource limits via setrlimit(2) for the values in the
    204  * two-dimensional array of integers that's passed in. The second dimension
    205  * contains a tuple of length 3: (resource, rlim_cur, rlim_max). NULL is
    206  * treated as an empty array.
    207  *
    208  * -1 is returned on error.
    209  */
    210 static int setrlimitsFromArray(ArrayObject* rlimits)
    211 {
    212     u4 i;
    213     struct rlimit rlim;
    214 
    215     if (rlimits == NULL) {
    216         return 0;
    217     }
    218 
    219     memset (&rlim, 0, sizeof(rlim));
    220 
    221     ArrayObject** tuples = (ArrayObject **)(void *)rlimits->contents;
    222 
    223     for (i = 0; i < rlimits->length; i++) {
    224         ArrayObject * rlimit_tuple = tuples[i];
    225         s4* contents = (s4 *)(void *)rlimit_tuple->contents;
    226         int err;
    227 
    228         if (rlimit_tuple->length != 3) {
    229             ALOGE("rlimits array must have a second dimension of size 3");
    230             return -1;
    231         }
    232 
    233         rlim.rlim_cur = contents[1];
    234         rlim.rlim_max = contents[2];
    235 
    236         err = setrlimit(contents[0], &rlim);
    237 
    238         if (err < 0) {
    239             return -1;
    240         }
    241     }
    242 
    243     return 0;
    244 }
    245 
    246 /*
    247  * Create a private mount namespace and bind mount appropriate emulated
    248  * storage for the given user.
    249  */
    250 static int mountEmulatedStorage(uid_t uid, u4 mountMode) {
    251     // See storage config details at http://source.android.com/tech/storage/
    252     userid_t userid = multiuser_get_user_id(uid);
    253 
    254     // Create a second private mount namespace for our process
    255     if (unshare(CLONE_NEWNS) == -1) {
    256         ALOGE("Failed to unshare(): %s", strerror(errno));
    257         return -1;
    258     }
    259 
    260     // Create bind mounts to expose external storage
    261     if (mountMode == MOUNT_EXTERNAL_MULTIUSER
    262             || mountMode == MOUNT_EXTERNAL_MULTIUSER_ALL) {
    263         // These paths must already be created by init.rc
    264         const char* source = getenv("EMULATED_STORAGE_SOURCE");
    265         const char* target = getenv("EMULATED_STORAGE_TARGET");
    266         const char* legacy = getenv("EXTERNAL_STORAGE");
    267         if (source == NULL || target == NULL || legacy == NULL) {
    268             ALOGE("Storage environment undefined; unable to provide external storage");
    269             return -1;
    270         }
    271 
    272         // Prepare source paths
    273         char source_user[PATH_MAX];
    274         char source_obb[PATH_MAX];
    275         char target_user[PATH_MAX];
    276 
    277         // /mnt/shell/emulated/0
    278         snprintf(source_user, PATH_MAX, "%s/%d", source, userid);
    279         // /mnt/shell/emulated/obb
    280         snprintf(source_obb, PATH_MAX, "%s/obb", source);
    281         // /storage/emulated/0
    282         snprintf(target_user, PATH_MAX, "%s/%d", target, userid);
    283 
    284         if (fs_prepare_dir(source_user, 0000, 0, 0) == -1
    285                 || fs_prepare_dir(source_obb, 0000, 0, 0) == -1
    286                 || fs_prepare_dir(target_user, 0000, 0, 0) == -1) {
    287             return -1;
    288         }
    289 
    290         if (mountMode == MOUNT_EXTERNAL_MULTIUSER_ALL) {
    291             // Mount entire external storage tree for all users
    292             if (mount(source, target, NULL, MS_BIND, NULL) == -1) {
    293                 ALOGE("Failed to mount %s to %s: %s", source, target, strerror(errno));
    294                 return -1;
    295             }
    296         } else {
    297             // Only mount user-specific external storage
    298             if (mount(source_user, target_user, NULL, MS_BIND, NULL) == -1) {
    299                 ALOGE("Failed to mount %s to %s: %s", source_user, target_user, strerror(errno));
    300                 return -1;
    301             }
    302         }
    303 
    304         // Now that user is mounted, prepare and mount OBB storage
    305         // into place for current user
    306         char target_android[PATH_MAX];
    307         char target_obb[PATH_MAX];
    308 
    309         // /storage/emulated/0/Android
    310         snprintf(target_android, PATH_MAX, "%s/%d/Android", target, userid);
    311         // /storage/emulated/0/Android/obb
    312         snprintf(target_obb, PATH_MAX, "%s/%d/Android/obb", target, userid);
    313 
    314         if (fs_prepare_dir(target_android, 0000, 0, 0) == -1
    315                 || fs_prepare_dir(target_obb, 0000, 0, 0) == -1
    316                 || fs_prepare_dir(legacy, 0000, 0, 0) == -1) {
    317             return -1;
    318         }
    319         if (mount(source_obb, target_obb, NULL, MS_BIND, NULL) == -1) {
    320             ALOGE("Failed to mount %s to %s: %s", source_obb, target_obb, strerror(errno));
    321             return -1;
    322         }
    323 
    324         // Finally, mount user-specific path into place for legacy users
    325         if (mount(target_user, legacy, NULL, MS_BIND | MS_REC, NULL) == -1) {
    326             ALOGE("Failed to mount %s to %s: %s", target_user, legacy, strerror(errno));
    327             return -1;
    328         }
    329 
    330     } else {
    331         ALOGE("Mount mode %d unsupported", mountMode);
    332         return -1;
    333     }
    334 
    335     return 0;
    336 }
    337 
    338 /* native public static int fork(); */
    339 static void Dalvik_dalvik_system_Zygote_fork(const u4* args, JValue* pResult)
    340 {
    341     pid_t pid;
    342 
    343     if (!gDvm.zygote) {
    344         dvmThrowIllegalStateException(
    345             "VM instance not started with -Xzygote");
    346 
    347         RETURN_VOID();
    348     }
    349 
    350     if (!dvmGcPreZygoteFork()) {
    351         ALOGE("pre-fork heap failed");
    352         dvmAbort();
    353     }
    354 
    355     setSignalHandler();
    356 
    357     dvmDumpLoaderStats("zygote");
    358     pid = fork();
    359 
    360 #ifdef HAVE_ANDROID_OS
    361     if (pid == 0) {
    362         /* child process */
    363         extern int gMallocLeakZygoteChild;
    364         gMallocLeakZygoteChild = 1;
    365     }
    366 #endif
    367 
    368     RETURN_INT(pid);
    369 }
    370 
    371 /*
    372  * Enable/disable debug features requested by the caller.
    373  *
    374  * debugger
    375  *   If set, enable debugging; if not set, disable debugging.  This is
    376  *   easy to handle, because the JDWP thread isn't started until we call
    377  *   dvmInitAfterZygote().
    378  * checkjni
    379  *   If set, make sure "check JNI" is enabled.
    380  * assert
    381  *   If set, make sure assertions are enabled.  This gets fairly weird,
    382  *   because it affects the result of a method called by class initializers,
    383  *   and hence can't affect pre-loaded/initialized classes.
    384  * safemode
    385  *   If set, operates the VM in the safe mode. The definition of "safe mode" is
    386  *   implementation dependent and currently only the JIT compiler is disabled.
    387  *   This is easy to handle because the compiler thread and associated resources
    388  *   are not requested until we call dvmInitAfterZygote().
    389  */
    390 static void enableDebugFeatures(u4 debugFlags)
    391 {
    392     ALOGV("debugFlags is 0x%02x", debugFlags);
    393 
    394     gDvm.jdwpAllowed = ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0);
    395 
    396     if ((debugFlags & DEBUG_ENABLE_CHECKJNI) != 0) {
    397         /* turn it on if it's not already enabled */
    398         dvmLateEnableCheckedJni();
    399     }
    400 
    401     if ((debugFlags & DEBUG_ENABLE_JNI_LOGGING) != 0) {
    402         gDvmJni.logThirdPartyJni = true;
    403     }
    404 
    405     if ((debugFlags & DEBUG_ENABLE_ASSERT) != 0) {
    406         /* turn it on if it's not already enabled */
    407         dvmLateEnableAssertions();
    408     }
    409 
    410     if ((debugFlags & DEBUG_ENABLE_SAFEMODE) != 0) {
    411 #if defined(WITH_JIT)
    412         /* turn off the jit if it is explicitly requested by the app */
    413         if (gDvm.executionMode == kExecutionModeJit)
    414             gDvm.executionMode = kExecutionModeInterpFast;
    415 #endif
    416     }
    417 
    418 #ifdef HAVE_ANDROID_OS
    419     if ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0) {
    420         /* To let a non-privileged gdbserver attach to this
    421          * process, we must set its dumpable bit flag. However
    422          * we are not interested in generating a coredump in
    423          * case of a crash, so also set the coredump size to 0
    424          * to disable that
    425          */
    426         if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) {
    427             ALOGE("could not set dumpable bit flag for pid %d: %s",
    428                  getpid(), strerror(errno));
    429         } else {
    430             struct rlimit rl;
    431             rl.rlim_cur = 0;
    432             rl.rlim_max = RLIM_INFINITY;
    433             if (setrlimit(RLIMIT_CORE, &rl) < 0) {
    434                 ALOGE("could not disable core file generation for pid %d: %s",
    435                     getpid(), strerror(errno));
    436             }
    437         }
    438     }
    439 #endif
    440 }
    441 
    442 /*
    443  * Set Linux capability flags.
    444  *
    445  * Returns 0 on success, errno on failure.
    446  */
    447 static int setCapabilities(int64_t permitted, int64_t effective)
    448 {
    449 #ifdef HAVE_ANDROID_OS
    450     struct __user_cap_header_struct capheader;
    451     struct __user_cap_data_struct capdata;
    452 
    453     memset(&capheader, 0, sizeof(capheader));
    454     memset(&capdata, 0, sizeof(capdata));
    455 
    456     capheader.version = _LINUX_CAPABILITY_VERSION;
    457     capheader.pid = 0;
    458 
    459     capdata.effective = effective;
    460     capdata.permitted = permitted;
    461 
    462     ALOGV("CAPSET perm=%llx eff=%llx", permitted, effective);
    463     if (capset(&capheader, &capdata) != 0)
    464         return errno;
    465 #endif /*HAVE_ANDROID_OS*/
    466 
    467     return 0;
    468 }
    469 
    470 /*
    471  * Set SELinux security context.
    472  *
    473  * Returns 0 on success, -1 on failure.
    474  */
    475 static int setSELinuxContext(uid_t uid, bool isSystemServer,
    476                              const char *seInfo, const char *niceName)
    477 {
    478 #ifdef HAVE_ANDROID_OS
    479     return selinux_android_setcontext(uid, isSystemServer, seInfo, niceName);
    480 #else
    481     return 0;
    482 #endif
    483 }
    484 
    485 static bool needsNoRandomizeWorkaround() {
    486 #if !defined(__arm__)
    487     return false;
    488 #else
    489     int major;
    490     int minor;
    491     struct utsname uts;
    492     if (uname(&uts) == -1) {
    493         return false;
    494     }
    495 
    496     if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
    497         return false;
    498     }
    499 
    500     // Kernels before 3.4.* need the workaround.
    501     return (major < 3) || ((major == 3) && (minor < 4));
    502 #endif
    503 }
    504 
    505 /*
    506  * Utility routine to fork zygote and specialize the child process.
    507  */
    508 static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
    509 {
    510     pid_t pid;
    511 
    512     uid_t uid = (uid_t) args[0];
    513     gid_t gid = (gid_t) args[1];
    514     ArrayObject* gids = (ArrayObject *)args[2];
    515     u4 debugFlags = args[3];
    516     ArrayObject *rlimits = (ArrayObject *)args[4];
    517     u4 mountMode = MOUNT_EXTERNAL_NONE;
    518     int64_t permittedCapabilities, effectiveCapabilities;
    519     char *seInfo = NULL;
    520     char *niceName = NULL;
    521 
    522     if (isSystemServer) {
    523         /*
    524          * Don't use GET_ARG_LONG here for now.  gcc is generating code
    525          * that uses register d8 as a temporary, and that's coming out
    526          * scrambled in the child process.  b/3138621
    527          */
    528         //permittedCapabilities = GET_ARG_LONG(args, 5);
    529         //effectiveCapabilities = GET_ARG_LONG(args, 7);
    530         permittedCapabilities = args[5] | (int64_t) args[6] << 32;
    531         effectiveCapabilities = args[7] | (int64_t) args[8] << 32;
    532     } else {
    533         mountMode = args[5];
    534         permittedCapabilities = effectiveCapabilities = 0;
    535         StringObject* seInfoObj = (StringObject*)args[6];
    536         if (seInfoObj) {
    537             seInfo = dvmCreateCstrFromString(seInfoObj);
    538             if (!seInfo) {
    539                 ALOGE("seInfo dvmCreateCstrFromString failed");
    540                 dvmAbort();
    541             }
    542         }
    543         StringObject* niceNameObj = (StringObject*)args[7];
    544         if (niceNameObj) {
    545             niceName = dvmCreateCstrFromString(niceNameObj);
    546             if (!niceName) {
    547                 ALOGE("niceName dvmCreateCstrFromString failed");
    548                 dvmAbort();
    549             }
    550         }
    551     }
    552 
    553     if (!gDvm.zygote) {
    554         dvmThrowIllegalStateException(
    555             "VM instance not started with -Xzygote");
    556 
    557         return -1;
    558     }
    559 
    560     if (!dvmGcPreZygoteFork()) {
    561         ALOGE("pre-fork heap failed");
    562         dvmAbort();
    563     }
    564 
    565     setSignalHandler();
    566 
    567     dvmDumpLoaderStats("zygote");
    568     pid = fork();
    569 
    570     if (pid == 0) {
    571         int err;
    572         /* The child process */
    573 
    574 #ifdef HAVE_ANDROID_OS
    575         extern int gMallocLeakZygoteChild;
    576         gMallocLeakZygoteChild = 1;
    577 
    578         /* keep caps across UID change, unless we're staying root */
    579         if (uid != 0) {
    580             err = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
    581 
    582             if (err < 0) {
    583                 ALOGE("cannot PR_SET_KEEPCAPS: %s", strerror(errno));
    584                 dvmAbort();
    585             }
    586         }
    587 
    588         for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
    589             err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
    590             if (err < 0) {
    591                 if (errno == EINVAL) {
    592                     ALOGW("PR_CAPBSET_DROP %d failed: %s. "
    593                           "Please make sure your kernel is compiled with "
    594                           "file capabilities support enabled.",
    595                           i, strerror(errno));
    596                 } else {
    597                     ALOGE("PR_CAPBSET_DROP %d failed: %s.", i, strerror(errno));
    598                     dvmAbort();
    599                 }
    600             }
    601         }
    602 
    603 #endif /* HAVE_ANDROID_OS */
    604 
    605         if (mountMode != MOUNT_EXTERNAL_NONE) {
    606             err = mountEmulatedStorage(uid, mountMode);
    607             if (err < 0) {
    608                 ALOGE("cannot mountExternalStorage(): %s", strerror(errno));
    609 
    610                 if (errno == ENOTCONN || errno == EROFS) {
    611                     // When device is actively encrypting, we get ENOTCONN here
    612                     // since FUSE was mounted before the framework restarted.
    613                     // When encrypted device is booting, we get EROFS since
    614                     // FUSE hasn't been created yet by init.
    615                     // In either case, continue without external storage.
    616                 } else {
    617                     dvmAbort();
    618                 }
    619             }
    620         }
    621 
    622         err = setgroupsIntarray(gids);
    623         if (err < 0) {
    624             ALOGE("cannot setgroups(): %s", strerror(errno));
    625             dvmAbort();
    626         }
    627 
    628         err = setrlimitsFromArray(rlimits);
    629         if (err < 0) {
    630             ALOGE("cannot setrlimit(): %s", strerror(errno));
    631             dvmAbort();
    632         }
    633 
    634         err = setresgid(gid, gid, gid);
    635         if (err < 0) {
    636             ALOGE("cannot setresgid(%d): %s", gid, strerror(errno));
    637             dvmAbort();
    638         }
    639 
    640         err = setresuid(uid, uid, uid);
    641         if (err < 0) {
    642             ALOGE("cannot setresuid(%d): %s", uid, strerror(errno));
    643             dvmAbort();
    644         }
    645 
    646         if (needsNoRandomizeWorkaround()) {
    647             int current = personality(0xffffFFFF);
    648             int success = personality((ADDR_NO_RANDOMIZE | current));
    649             if (success == -1) {
    650                 ALOGW("Personality switch failed. current=%d error=%d\n", current, errno);
    651             }
    652         }
    653 
    654         err = setCapabilities(permittedCapabilities, effectiveCapabilities);
    655         if (err != 0) {
    656             ALOGE("cannot set capabilities (%llx,%llx): %s",
    657                 permittedCapabilities, effectiveCapabilities, strerror(err));
    658             dvmAbort();
    659         }
    660 
    661         err = set_sched_policy(0, SP_DEFAULT);
    662         if (err < 0) {
    663             ALOGE("cannot set_sched_policy(0, SP_DEFAULT): %s", strerror(-err));
    664             dvmAbort();
    665         }
    666 
    667         err = setSELinuxContext(uid, isSystemServer, seInfo, niceName);
    668         if (err < 0) {
    669             ALOGE("cannot set SELinux context: %s\n", strerror(errno));
    670             dvmAbort();
    671         }
    672         // These free(3) calls are safe because we know we're only ever forking
    673         // a single-threaded process, so we know no other thread held the heap
    674         // lock when we forked.
    675         free(seInfo);
    676         free(niceName);
    677 
    678         /*
    679          * Our system thread ID has changed.  Get the new one.
    680          */
    681         Thread* thread = dvmThreadSelf();
    682         thread->systemTid = dvmGetSysThreadId();
    683 
    684         /* configure additional debug options */
    685         enableDebugFeatures(debugFlags);
    686 
    687         unsetSignalHandler();
    688         gDvm.zygote = false;
    689         if (!dvmInitAfterZygote()) {
    690             ALOGE("error in post-zygote initialization");
    691             dvmAbort();
    692         }
    693     } else if (pid > 0) {
    694         /* the parent process */
    695         free(seInfo);
    696         free(niceName);
    697     }
    698 
    699     return pid;
    700 }
    701 
    702 /*
    703  * native public static int nativeForkAndSpecialize(int uid, int gid,
    704  *     int[] gids, int debugFlags, int[][] rlimits, int mountExternal,
    705  *     String seInfo, String niceName);
    706  */
    707 static void Dalvik_dalvik_system_Zygote_forkAndSpecialize(const u4* args,
    708     JValue* pResult)
    709 {
    710     pid_t pid;
    711 
    712     pid = forkAndSpecializeCommon(args, false);
    713 
    714     RETURN_INT(pid);
    715 }
    716 
    717 /*
    718  * native public static int nativeForkSystemServer(int uid, int gid,
    719  *     int[] gids, int debugFlags, int[][] rlimits,
    720  *     long permittedCapabilities, long effectiveCapabilities);
    721  */
    722 static void Dalvik_dalvik_system_Zygote_forkSystemServer(
    723         const u4* args, JValue* pResult)
    724 {
    725     pid_t pid;
    726     pid = forkAndSpecializeCommon(args, true);
    727 
    728     /* The zygote process checks whether the child process has died or not. */
    729     if (pid > 0) {
    730         int status;
    731 
    732         ALOGI("System server process %d has been created", pid);
    733         gDvm.systemServerPid = pid;
    734         /* There is a slight window that the system server process has crashed
    735          * but it went unnoticed because we haven't published its pid yet. So
    736          * we recheck here just to make sure that all is well.
    737          */
    738         if (waitpid(pid, &status, WNOHANG) == pid) {
    739             ALOGE("System server process %d has died. Restarting Zygote!", pid);
    740             kill(getpid(), SIGKILL);
    741         }
    742     }
    743     RETURN_INT(pid);
    744 }
    745 
    746 const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {
    747     { "nativeFork", "()I",
    748       Dalvik_dalvik_system_Zygote_fork },
    749     { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;)I",
    750       Dalvik_dalvik_system_Zygote_forkAndSpecialize },
    751     { "nativeForkSystemServer", "(II[II[[IJJ)I",
    752       Dalvik_dalvik_system_Zygote_forkSystemServer },
    753     { NULL, NULL, NULL },
    754 };
    755