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