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