com_android_internal_os_Zygote.cpp revision 31b1b2766d80a9a1979488e57a49d1015cfb5538
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "Zygote"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc
209b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li#include <sys/mount.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/fs.h>
229b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <list>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <grp.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <inttypes.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <mntent.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <paths.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <signal.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/capability.h>
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/personality.h>
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/prctl.h>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/resource.h>
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h>
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h>
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/utsname.h>
40df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include <sys/wait.h>
417478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li#include <unistd.h>
427478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li
43df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include <cutils/fs.h>
44df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include <cutils/multiuser.h>
457478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li#include <cutils/sched_policy.h>
467478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li#include <private/android_filesystem_config.h>
47df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include <utils/String8.h>
48df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include <selinux/android.h>
49df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include <processgroup/processgroup.h>
50df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main
51df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include "core_jni_helpers.h"
52df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include "JNIHelp.h"
53df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include "ScopedLocalRef.h"
54df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main#include "ScopedPrimitiveArray.h"
557478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li#include "ScopedUtfChars.h"
56df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "nativebridge/native_bridge.h"
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace {
609b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
61c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparksusing android::String8;
62da83f4674a564007baac03db062a289c8158d940Benny Wong
63da83f4674a564007baac03db062a289c8158d940Benny Wongstatic pid_t gSystemServerPid = 0;
64da83f4674a564007baac03db062a289c8158d940Benny Wong
65da83f4674a564007baac03db062a289c8158d940Benny Wongstatic const char kZygoteClassName[] = "com/android/internal/os/Zygote";
66da83f4674a564007baac03db062a289c8158d940Benny Wongstatic jclass gZygoteClass;
67da83f4674a564007baac03db062a289c8158d940Benny Wongstatic jmethodID gCallPostForkChildHooks;
68da83f4674a564007baac03db062a289c8158d940Benny Wong
69da83f4674a564007baac03db062a289c8158d940Benny Wong// Must match values in com.android.internal.os.Zygote.
70da83f4674a564007baac03db062a289c8158d940Benny Wongenum MountExternalKind {
71da83f4674a564007baac03db062a289c8158d940Benny Wong  MOUNT_EXTERNAL_NONE = 0,
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  MOUNT_EXTERNAL_DEFAULT = 1,
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  MOUNT_EXTERNAL_READ = 2,
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  MOUNT_EXTERNAL_WRITE = 3,
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void RuntimeAbort(JNIEnv* env) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  env->FatalError("RuntimeAbort");
79e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks}
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
81e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks// This signal handler is for zygote mode, since the zygote must reap its children
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void SigChldHandler(int /*signal_number*/) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  pid_t pid;
8494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp  int status;
859b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     // Log process-death status that we care about.  In general it is
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     // not safe to call LOG(...) from a signal handler because of
899b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     // possible reentrancy.  However, we know a priori that the
909b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li     // current implementation of LOG() is safe to call from a SIGCHLD
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     // handler in the zygote process.  If the LOG() implementation
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     // changes its locking strategy or its use of syscalls within the
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     // lazy-init critical section, its use here may become unsafe.
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (WIFEXITED(status)) {
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      if (WEXITSTATUS(status)) {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      }
98e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    } else if (WIFSIGNALED(status)) {
99e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks      if (WTERMSIG(status) != SIGKILL) {
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      if (WCOREDUMP(status)) {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGI("Process %d dumped core.", pid);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If the just-crashed process is the system_server, bring down zygote
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // so that it is restarted by init and system server will be restarted
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // from there.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pid == gSystemServerPid) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      ALOGE("Exit zygote because system server (%d) has terminated", pid);
1129b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      kill(getpid(), SIGKILL);
1139b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    }
1149b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  }
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1169b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  // Note that we shouldn't consider ECHILD an error because
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // the secondary zygote might have no children left to wait for.
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (pid < 0 && errno != ECHILD) {
1199b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li// Configures the SIGCHLD handler for the zygote process. This is configured
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// very late, because earlier in the runtime we may fork() and exec()
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// other processes, and we want to waitpid() for those rather than
1269b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li// have them be harvested immediately.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This ends up being called repeatedly before each fork(), but there's
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// no real harm in that.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void SetSigChldHandler() {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  struct sigaction sa;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  memset(&sa, 0, sizeof(sa));
1339b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  sa.sa_handler = SigChldHandler;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  int err = sigaction(SIGCHLD, &sa, NULL);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (err < 0) {
1379b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Sets the SIGCHLD handler back to default behavior in zygote children.
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void UnsetSigChldHandler() {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  struct sigaction sa;
1449b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  memset(&sa, 0, sizeof(sa));
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  sa.sa_handler = SIG_DFL;
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  int err = sigaction(SIGCHLD, &sa, NULL);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (err < 0) {
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Calls POSIX setgroups() using the int[] object as an argument.
154ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li// A NULL argument is tolerated.
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void SetGids(JNIEnv* env, jintArray javaGids) {
156ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li  if (javaGids == NULL) {
1579b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    return;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
1599b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  ScopedIntArrayRO gids(env, javaGids);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (gids.get() == NULL) {
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      RuntimeAbort(env);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
164ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li  int rc = setgroups(gids.size(), reinterpret_cast<const gid_t*>(&gids[0]));
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (rc == -1) {
166ffe1cf251a4f8469695b8acfa37270684dc1b70cWu-cheng Li    ALOGE("setgroups failed");
1679b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    RuntimeAbort(env);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Sets the resource limits via setrlimit(2) for the values in the
1729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li// two-dimensional array of integers that's passed in. The second dimension
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// contains a tuple of length 3: (resource, rlim_cur, rlim_max). NULL is
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// treated as an empty array.
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void SetRLimits(JNIEnv* env, jobjectArray javaRlimits) {
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (javaRlimits == NULL) {
177b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li    return;
178b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li  }
179b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li
180b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li  rlimit rlim;
181b8a10fe45657f2dcc50cae8a06805f8438a6937eWu-cheng Li  memset(&rlim, 0, sizeof(rlim));
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  for (int i = 0; i < env->GetArrayLength(javaRlimits); ++i) {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ScopedLocalRef<jobject> javaRlimitObject(env, env->GetObjectArrayElement(javaRlimits, i));
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ScopedIntArrayRO javaRlimit(env, reinterpret_cast<jintArray>(javaRlimitObject.get()));
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (javaRlimit.size() != 3) {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      ALOGE("rlimits array must have a second dimension of size 3");
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      RuntimeAbort(env);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    rlim.rlim_cur = javaRlimit[1];
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    rlim.rlim_max = javaRlimit[2];
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
194df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main    int rc = setrlimit(javaRlimit[0], &rlim);
1957478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li    if (rc == -1) {
196df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main      ALOGE("setrlimit(%d, {%ld, %ld}) failed", javaRlimit[0], rlim.rlim_cur,
197da0a56df963353a1f1bd1914fa31f870d982dd5aScott Main            rlim.rlim_max);
1989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      RuntimeAbort(env);
1999b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// The debug malloc library needs to know whether it's the zygote or a child.
2049b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Liextern "C" int gMallocLeakZygoteChild;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void EnableKeepCapabilities(JNIEnv* env) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  int rc = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (rc == -1) {
2099b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    ALOGE("prctl(PR_SET_KEEPCAPS) failed");
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    RuntimeAbort(env);
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Listatic void DropCapabilitiesBoundingSet(JNIEnv* env) {
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rc == -1) {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      if (errno == EINVAL) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project              "your kernel is compiled with file capabilities support");
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      } else {
2229b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li        ALOGE("prctl(PR_CAPBSET_DROP) failed");
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RuntimeAbort(env);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void SetCapabilities(JNIEnv* env, int64_t permitted, int64_t effective) {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  __user_cap_header_struct capheader;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  memset(&capheader, 0, sizeof(capheader));
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  capheader.version = _LINUX_CAPABILITY_VERSION_3;
23394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp  capheader.pid = 0;
234a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks
235a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks  __user_cap_data_struct capdata[2];
23694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp  memset(&capdata, 0, sizeof(capdata));
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  capdata[0].effective = effective;
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  capdata[1].effective = effective >> 32;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  capdata[0].permitted = permitted;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  capdata[1].permitted = permitted >> 32;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (capset(&capheader, &capdata[0]) == -1) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOGE("capset(%" PRId64 ", %" PRId64 ") failed", permitted, effective);
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    RuntimeAbort(env);
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
24694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp}
24794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp
24894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harpstatic void SetSchedulerPolicy(JNIEnv* env) {
24994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp  errno = -set_sched_policy(0, SP_DEFAULT);
25094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp  if (errno != 0) {
25194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    ALOGE("set_sched_policy(0, SP_DEFAULT) failed");
25294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    RuntimeAbort(env);
25394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp  }
25494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp}
25594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp
25694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harpstatic int UnmountTree(const char* path) {
25794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    size_t path_len = strlen(path);
25894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp
25994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    FILE* fp = setmntent("/proc/mounts", "r");
26094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    if (fp == NULL) {
26194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        ALOGE("Error opening /proc/mounts: %s", strerror(errno));
26294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        return -errno;
26394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    }
26494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp
26594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    // Some volumes can be stacked on each other, so force unmount in
26694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    // reverse order to give us the best chance of success.
26794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    std::list<std::string> toUnmount;
26894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    mntent* mentry;
26994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    while ((mentry = getmntent(fp)) != NULL) {
27094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
27194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp            toUnmount.push_front(std::string(mentry->mnt_dir));
27294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    endmntent(fp);
27594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp
27694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    for (auto path : toUnmount) {
27794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        if (umount2(path.c_str(), MNT_DETACH)) {
27894927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp            ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
27994927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        }
28094927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    }
28194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp    return 0;
28294927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp}
28394927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp
28494927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp// Create a private mount namespace and bind mount appropriate emulated
28594927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp// storage for the given user.
28694927dffce1626898b59579dfc5af53b5de8cef6Andrew Harpstatic bool MountEmulatedStorage(uid_t uid, jint mount_mode,
28794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp        bool force_mount_namespace) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // See storage config details at http://source.android.com/tech/storage/
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Create a second private mount namespace for our process
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (unshare(CLONE_NEWNS) == -1) {
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGW("Failed to unshare(): %s", strerror(errno));
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Unmount storage provided by root namespace and mount requested view
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    UnmountTree("/storage");
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 storageSource;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
301c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks        storageSource = "/mnt/runtime/default";
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (mount_mode == MOUNT_EXTERNAL_READ) {
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        storageSource = "/mnt/runtime/read";
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (mount_mode == MOUNT_EXTERNAL_WRITE) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        storageSource = "/mnt/runtime/write";
306c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks    } else {
307c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks        // Sane default of no storage visible
308e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks        return true;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
310e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGW("Failed to mount %s to /storage: %s", storageSource.string(), strerror(errno));
313c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks        return false;
314e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
316e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    // Mount user-specific symlink helper into place
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    userid_t user_id = multiuser_get_user_id(uid);
3189b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    const String8 userSource(String8::format("/mnt/user/%d", user_id));
319c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks    if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
321a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks    }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
323a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks            NULL, MS_BIND, NULL)) == -1) {
324a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks        ALOGW("Failed to mount %s to /storage/self: %s", userSource.string(), strerror(errno));
325a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks        return false;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
32794927dffce1626898b59579dfc5af53b5de8cef6Andrew Harp
328a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks    return true;
329a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks}
330a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks
33194927dffce1626898b59579dfc5af53b5de8cef6Andrew Harpstatic bool NeedsNoRandomizeWorkaround() {
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if !defined(__arm__)
333a6118c6383c6f5703a576d08586a340fd71d28a4Dave Sparks    return false;
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int major;
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int minor;
337e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    struct utsname uts;
338e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    if (uname(&uts) == -1) {
339e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks        return false;
340e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    }
341e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
342e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
343c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks        return false;
344e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
346e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    // Kernels before 3.4.* need the workaround.
347e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    return (major < 3) || ((major == 3) && (minor < 4));
348e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks#endif
349e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks}
350e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
35136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li// Utility to close down the Zygote socket file descriptors while
352e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks// the child is still running as root with Zygote's privileges.  Each
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// descriptor (if any) is closed via dup2(), replacing it with a valid
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// (open) descriptor to /dev/null.
355c62f9bd13327937aa2d2f20b44215397120634c1Dave Sparks
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void DetachDescriptors(JNIEnv* env, jintArray fdsToClose) {
357e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks  if (!fdsToClose) {
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return;
359e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks  }
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  jsize count = env->GetArrayLength(fdsToClose);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  ScopedIntArrayRO ar(env, fdsToClose);
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (ar.get() == NULL) {
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      ALOGE("Bad fd array");
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      RuntimeAbort(env);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  jsize i;
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  int devnull;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  for (i = 0; i < count; i++) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    devnull = open("/dev/null", O_RDWR);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (devnull < 0) {
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      ALOGE("Failed to open /dev/null: %s", strerror(errno));
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      RuntimeAbort(env);
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      continue;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ALOGV("Switching descriptor %d to /dev/null: %s", ar[i], strerror(errno));
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dup2(devnull, ar[i]) < 0) {
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      ALOGE("Failed dup2() on descriptor %d: %s", ar[i], strerror(errno));
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      RuntimeAbort(env);
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    close(devnull);
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3847478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Livoid SetThreadName(const char* thread_name) {
3857478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li  bool hasAt = false;
386df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main  bool hasDot = false;
387df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main  const char* s = thread_name;
3887478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li  while (*s) {
389df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main    if (*s == '.') {
390df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main      hasDot = true;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (*s == '@') {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      hasAt = true;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s++;
3959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  }
3969b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  const int len = s - thread_name;
3979b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  if (len < 15 || hasAt || !hasDot) {
3989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    s = thread_name;
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  } else {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = thread_name + len - 15;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  // pthread_setname_np fails rather than truncating long strings.
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  char buf[16];       // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  strlcpy(buf, s, sizeof(buf)-1);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  errno = pthread_setname_np(pthread_self(), buf);
4069b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  if (errno != 0) {
40736322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li    ALOGW("Unable to set the name of current thread to '%s': %s", buf, strerror(errno));
40836322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li  }
40936322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li}
41036322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li
41136322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Li#ifdef ENABLE_SCHED_BOOST
41236322db5752c7ec196f59ba94abe5d5a63cc19f5Wu-cheng Listatic void SetForkLoad(bool boost) {
413da0a56df963353a1f1bd1914fa31f870d982dd5aScott Main  // set scheduler knob to boost forked processes
4147478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li  pid_t currentPid = getpid();
4157478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li  // fits at most "/proc/XXXXXXX/sched_init_task_load\0"
416df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main  char schedPath[35];
417df4578e8ab7008a7e528d5af2ae761b33cf2bdf4Scott Main  snprintf(schedPath, sizeof(schedPath), "/proc/%u/sched_init_task_load", currentPid);
418068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li  int schedBoostFile = open(schedPath, O_WRONLY);
419068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li  if (schedBoostFile < 0) {
420068ef42c3ffe1eccec10f97f08541304f679fe67Wu-cheng Li    ALOGW("Unable to set zygote scheduler boost");
4217478ea6848c0059e65a4089b4ec2ff4158520870Wu-cheng Li    return;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (boost) {
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    write(schedBoostFile, "100\0", 4);
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  } else {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    write(schedBoostFile, "0\0", 2);
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  close(schedBoostFile);
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
432244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang// Utility routine to fork zygote and specialize the child process.
433244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Changstatic pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
434244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang                                     jint debug_flags, jobjectArray javaRlimits,
435244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang                                     jlong permittedCapabilities, jlong effectiveCapabilities,
436244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang                                     jint mount_external,
437244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang                                     jstring java_se_info, jstring java_se_name,
438244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang                                     bool is_system_server, jintArray fdsToClose,
439244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang                                     jstring instructionSet, jstring dataDir) {
440244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang  SetSigChldHandler();
441244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang
442244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang#ifdef ENABLE_SCHED_BOOST
443244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang  SetForkLoad(true);
444244f8c26365a303d9dd861bd48a29a4b48578da1Chih-Chung Chang#endif
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  pid_t pid = fork();
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (pid == 0) {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // The child process.
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gMallocLeakZygoteChild = 1;
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Clean up any descriptors which must be closed immediately
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DetachDescriptors(env, fdsToClose);
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Keep capabilities across UID change, unless we're staying root.
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (uid != 0) {
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      EnableKeepCapabilities(env);
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DropCapabilitiesBoundingSet(env);
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4629b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    bool use_native_bridge = !is_system_server && (instructionSet != NULL)
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        && android::NativeBridgeAvailable();
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (use_native_bridge) {
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      ScopedUtfChars isa_string(env, instructionSet);
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      use_native_bridge = android::NeedsNativeBridge(isa_string.c_str());
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (use_native_bridge && dataDir == NULL) {
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      // dataDir should never be null if we need to use a native bridge.
4709b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      // In general, dataDir will never be null for normal applications. It can only happen in
4719b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      // special cases (for isolated processes which are not associated with any app). These are
4729b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      // launched by the framework and should not be emulated anyway.
4739b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      use_native_bridge = false;
4749b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      ALOGW("Native bridge will not be used because dataDir == NULL.");
4759b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    }
4769b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
4779b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    if (!MountEmulatedStorage(uid, mount_external, use_native_bridge)) {
4789b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      ALOGW("Failed to mount emulated storage: %s", strerror(errno));
4799b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      if (errno == ENOTCONN || errno == EROFS) {
48040057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li        // When device is actively encrypting, we get ENOTCONN here
48140057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li        // since FUSE was mounted before the framework restarted.
48240057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li        // When encrypted device is booting, we get EROFS since
48340057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li        // FUSE hasn't been created yet by init.
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // In either case, continue without external storage.
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      } else {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ALOGE("Cannot continue without emulated storage");
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RuntimeAbort(env);
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      }
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
490e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
491e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    if (!is_system_server) {
492e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks        int rc = createProcessGroup(uid, getpid());
493e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks        if (rc != 0) {
494e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks            if (rc == -EROFS) {
4959b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li                ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
4969b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li            } else {
4979b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li                ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));
4989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li            }
4999b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li        }
5009b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    }
5019b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
5029b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    SetGids(env, javaGids);
5039b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
5049b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li    SetRLimits(env, javaRlimits);
5059b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
506e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    if (use_native_bridge) {
50740057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li      ScopedUtfChars isa_string(env, instructionSet);
50840057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li      ScopedUtfChars data_dir(env, dataDir);
50940057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li      android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());
51040057ce749c8c4d274db0352a2af4344bda92dbaWu-cheng Li    }
511e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
512e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    int rc = setresgid(gid, gid, gid);
513e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    if (rc == -1) {
514e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks      ALOGE("setresgid(%d) failed: %s", gid, strerror(errno));
515e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks      RuntimeAbort(env);
516e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    }
517e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    rc = setresuid(uid, uid, uid);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (rc == -1) {
520e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks      ALOGE("setresuid(%d) failed: %s", uid, strerror(errno));
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      RuntimeAbort(env);
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NeedsNoRandomizeWorkaround()) {
525e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks        // Work around ARM kernel ASLR lossage (http://b/5817320).
52636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li        int old_personality = personality(0xffffffff);
52736f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li        int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
52836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li        if (new_personality == -1) {
52936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li            ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
53036f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li        }
53136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    }
53236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li
53336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    SetCapabilities(env, permittedCapabilities, effectiveCapabilities);
53436f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li
53536f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    SetSchedulerPolicy(env);
53636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li
53736f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    const char* se_info_c_str = NULL;
53836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    ScopedUtfChars* se_info = NULL;
53936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    if (java_se_info != NULL) {
54036f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li        se_info = new ScopedUtfChars(env, java_se_info);
54136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li        se_info_c_str = se_info->c_str();
54236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li        if (se_info_c_str == NULL) {
54336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li          ALOGE("se_info_c_str == NULL");
54436f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li          RuntimeAbort(env);
54536f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li        }
546d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang    }
547d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang    const char* se_name_c_str = NULL;
548d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang    ScopedUtfChars* se_name = NULL;
549d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang    if (java_se_name != NULL) {
550d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang        se_name = new ScopedUtfChars(env, java_se_name);
551d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang        se_name_c_str = se_name->c_str();
552d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang        if (se_name_c_str == NULL) {
553d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang          ALOGE("se_name_c_str == NULL");
554d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang          RuntimeAbort(env);
555e7bd22a9d9441916aa9c67d80ee9f02a2d3e10e5Chih-Chung Chang        }
556e7bd22a9d9441916aa9c67d80ee9f02a2d3e10e5Chih-Chung Chang    }
557d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang    rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
558d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang    if (rc == -1) {
559d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang      ALOGE("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
560d1d7706fce19a9a0cf71ff9b65f3aba9b89eeb3bChih-Chung Chang            is_system_server, se_info_c_str, se_name_c_str);
561e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks      RuntimeAbort(env);
56277153ee04e4172cb0e123cadaa1e76671dbd840eWu-cheng Li    }
56377153ee04e4172cb0e123cadaa1e76671dbd840eWu-cheng Li
564e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    // Make it easier to debug audit logs by setting the main thread's name to the
565e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    // nice name rather than "app_process".
566e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    if (se_info_c_str == NULL && is_system_server) {
567e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks      se_name_c_str = "system_server";
568e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    }
56936f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    if (se_info_c_str != NULL) {
57036f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li      SetThreadName(se_name_c_str);
57136f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    }
57236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li
57336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    delete se_info;
57436f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    delete se_name;
575e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
57636f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    UnsetSigChldHandler();
577e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
57836f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
579e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks                              is_system_server ? NULL : instructionSet);
580e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    if (env->ExceptionCheck()) {
581e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks      ALOGE("Error calling post fork hooks.");
58236f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li      RuntimeAbort(env);
58336f68b8f24df906c969581b0b8e1a47f95dc03cbWu-cheng Li    }
584e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks  } else if (pid > 0) {
58577153ee04e4172cb0e123cadaa1e76671dbd840eWu-cheng Li    // the parent process
586e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks
587e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks#ifdef ENABLE_SCHED_BOOST
588e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    // unset scheduler knob
589e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks    SetForkLoad(false);
590e8b26e197f7c5e4acbdf8a5cd3f014fbc242c8abDave Sparks#endif
5919b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
592a1b653d41df9a7999e1dba2a508295671ff6771dJames Dong  }
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return pid;
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}  // anonymous namespace
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
5989b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint debug_flags, jobjectArray rlimits,
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint mount_external, jstring se_info, jstring se_name,
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Grant CAP_WAKE_ALARM to the Bluetooth process.
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jlong capabilities = 0;
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (uid == AID_BLUETOOTH) {
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        capabilities |= (1LL << CAP_WAKE_ALARM);
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            rlimits, capabilities, capabilities, mount_external, se_info,
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            se_name, false, fdsToClose, instructionSet, appDataDir);
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint com_android_internal_os_Zygote_nativeForkSystemServer(
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jlong effectiveCapabilities) {
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      debug_flags, rlimits,
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      permittedCapabilities, effectiveCapabilities,
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      NULL, NULL);
6249b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  if (pid > 0) {
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      // The zygote process checks whether the child process has died or not.
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      ALOGI("System server process %d has been created", pid);
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      gSystemServerPid = pid;
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      // There is a slight window that the system server process has crashed
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      // but it went unnoticed because we haven't published its pid yet. So
6309b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li      // we recheck here just to make sure that all is well.
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      int status;
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      if (waitpid(pid, &status, WNOHANG) == pid) {
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          ALOGE("System server process %d has died. Restarting Zygote!", pid);
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          RuntimeAbort(env);
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      }
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  }
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return pid;
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "nativeForkAndSpecialize",
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I",
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "nativeForkSystemServer", "(II[II[[IJJ)I",
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      (void *) com_android_internal_os_Zygote_nativeForkSystemServer }
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_com_android_internal_os_Zygote(JNIEnv* env) {
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass, "callPostForkChildHooks",
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                   "(ILjava/lang/String;)V");
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6539b6a8ab8221f2df20c32711b0f1e4f301165fac2Wu-cheng Li  return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods));
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}  // namespace android
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project