1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * dalvik.system.Zygote 19 */ 20 #include "Dalvik.h" 21 #include "native/InternalNativePriv.h" 22 23 #include <signal.h> 24 #include <sys/types.h> 25 #include <sys/wait.h> 26 #include <grp.h> 27 #include <errno.h> 28 29 #if defined(HAVE_PRCTL) 30 # include <sys/prctl.h> 31 #endif 32 33 #define ZYGOTE_LOG_TAG "Zygote" 34 35 /* must match values in dalvik.system.Zygote */ 36 enum { 37 DEBUG_ENABLE_DEBUGGER = 1, 38 DEBUG_ENABLE_CHECKJNI = 1 << 1, 39 DEBUG_ENABLE_ASSERT = 1 << 2, 40 DEBUG_ENABLE_SAFEMODE = 1 << 3, 41 }; 42 43 /* 44 * This signal handler is for zygote mode, since the zygote 45 * must reap its children 46 */ 47 static void sigchldHandler(int s) 48 { 49 pid_t pid; 50 int status; 51 52 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 53 /* Log process-death status that we care about. In general it is not 54 safe to call LOG(...) from a signal handler because of possible 55 reentrancy. However, we know a priori that the current implementation 56 of LOG() is safe to call from a SIGCHLD handler in the zygote process. 57 If the LOG() implementation changes its locking strategy or its use 58 of syscalls within the lazy-init critical section, its use here may 59 become unsafe. */ 60 if (WIFEXITED(status)) { 61 if (WEXITSTATUS(status)) { 62 LOG(LOG_DEBUG, ZYGOTE_LOG_TAG, "Process %d exited cleanly (%d)\n", 63 (int) pid, WEXITSTATUS(status)); 64 } else { 65 IF_LOGV(/*should use ZYGOTE_LOG_TAG*/) { 66 LOG(LOG_VERBOSE, ZYGOTE_LOG_TAG, 67 "Process %d exited cleanly (%d)\n", 68 (int) pid, WEXITSTATUS(status)); 69 } 70 } 71 } else if (WIFSIGNALED(status)) { 72 if (WTERMSIG(status) != SIGKILL) { 73 LOG(LOG_DEBUG, ZYGOTE_LOG_TAG, 74 "Process %d terminated by signal (%d)\n", 75 (int) pid, WTERMSIG(status)); 76 } else { 77 IF_LOGV(/*should use ZYGOTE_LOG_TAG*/) { 78 LOG(LOG_VERBOSE, ZYGOTE_LOG_TAG, 79 "Process %d terminated by signal (%d)\n", 80 (int) pid, WTERMSIG(status)); 81 } 82 } 83 #ifdef WCOREDUMP 84 if (WCOREDUMP(status)) { 85 LOG(LOG_INFO, ZYGOTE_LOG_TAG, "Process %d dumped core\n", 86 (int) pid); 87 } 88 #endif /* ifdef WCOREDUMP */ 89 } 90 91 /* 92 * If the just-crashed process is the system_server, bring down zygote 93 * so that it is restarted by init and system server will be restarted 94 * from there. 95 */ 96 if (pid == gDvm.systemServerPid) { 97 LOG(LOG_INFO, ZYGOTE_LOG_TAG, 98 "Exit zygote because system server (%d) has terminated\n", 99 (int) pid); 100 kill(getpid(), SIGKILL); 101 } 102 } 103 104 if (pid < 0) { 105 LOG(LOG_WARN, ZYGOTE_LOG_TAG, 106 "Zygote SIGCHLD error (%d) in waitpid\n",errno); 107 } 108 } 109 110 /* 111 * configure sigchld handler for the zygote process 112 * This is configured very late, because earlier in the dalvik lifecycle 113 * we can fork() and exec() for the verifier/optimizer, and we 114 * want to waitpid() for those rather than have them be harvested immediately. 115 * 116 * This ends up being called repeatedly before each fork(), but there's 117 * no real harm in that. 118 */ 119 static void setSignalHandler() 120 { 121 int err; 122 struct sigaction sa; 123 124 memset(&sa, 0, sizeof(sa)); 125 126 sa.sa_handler = sigchldHandler; 127 128 err = sigaction (SIGCHLD, &sa, NULL); 129 130 if (err < 0) { 131 LOGW("Error setting SIGCHLD handler errno: %d", errno); 132 } 133 } 134 135 /* 136 * Set the SIGCHLD handler back to default behavior in zygote children 137 */ 138 static void unsetSignalHandler() 139 { 140 int err; 141 struct sigaction sa; 142 143 memset(&sa, 0, sizeof(sa)); 144 145 sa.sa_handler = SIG_DFL; 146 147 err = sigaction (SIGCHLD, &sa, NULL); 148 149 if (err < 0) { 150 LOGW("Error unsetting SIGCHLD handler errno: %d", errno); 151 } 152 } 153 154 /* 155 * Calls POSIX setgroups() using the int[] object as an argument. 156 * A NULL argument is tolerated. 157 */ 158 159 static int setgroupsIntarray(ArrayObject* gidArray) 160 { 161 gid_t *gids; 162 u4 i; 163 s4 *contents; 164 165 if (gidArray == NULL) { 166 return 0; 167 } 168 169 /* just in case gid_t and u4 are different... */ 170 gids = alloca(sizeof(gid_t) * gidArray->length); 171 contents = (s4 *)gidArray->contents; 172 173 for (i = 0 ; i < gidArray->length ; i++) { 174 gids[i] = (gid_t) contents[i]; 175 } 176 177 return setgroups((size_t) gidArray->length, gids); 178 } 179 180 /* 181 * Sets the resource limits via setrlimit(2) for the values in the 182 * two-dimensional array of integers that's passed in. The second dimension 183 * contains a tuple of length 3: (resource, rlim_cur, rlim_max). NULL is 184 * treated as an empty array. 185 * 186 * -1 is returned on error. 187 */ 188 static int setrlimitsFromArray(ArrayObject* rlimits) 189 { 190 u4 i; 191 struct rlimit rlim; 192 193 if (rlimits == NULL) { 194 return 0; 195 } 196 197 memset (&rlim, 0, sizeof(rlim)); 198 199 ArrayObject** tuples = (ArrayObject **)(rlimits->contents); 200 201 for (i = 0; i < rlimits->length; i++) { 202 ArrayObject * rlimit_tuple = tuples[i]; 203 s4* contents = (s4 *)rlimit_tuple->contents; 204 int err; 205 206 if (rlimit_tuple->length != 3) { 207 LOGE("rlimits array must have a second dimension of size 3"); 208 return -1; 209 } 210 211 rlim.rlim_cur = contents[1]; 212 rlim.rlim_max = contents[2]; 213 214 err = setrlimit(contents[0], &rlim); 215 216 if (err < 0) { 217 return -1; 218 } 219 } 220 221 return 0; 222 } 223 224 /* native public static int fork(); */ 225 static void Dalvik_dalvik_system_Zygote_fork(const u4* args, JValue* pResult) 226 { 227 pid_t pid; 228 int err; 229 230 if (!gDvm.zygote) { 231 dvmThrowException("Ljava/lang/IllegalStateException;", 232 "VM instance not started with -Xzygote"); 233 234 RETURN_VOID(); 235 } 236 237 if (!dvmGcPreZygoteFork()) { 238 LOGE("pre-fork heap failed\n"); 239 dvmAbort(); 240 } 241 242 setSignalHandler(); 243 244 dvmDumpLoaderStats("zygote"); 245 pid = fork(); 246 247 #ifdef HAVE_ANDROID_OS 248 if (pid == 0) { 249 /* child process */ 250 extern int gMallocLeakZygoteChild; 251 gMallocLeakZygoteChild = 1; 252 } 253 #endif 254 255 RETURN_INT(pid); 256 } 257 258 /* 259 * Enable/disable debug features requested by the caller. 260 * 261 * debugger 262 * If set, enable debugging; if not set, disable debugging. This is 263 * easy to handle, because the JDWP thread isn't started until we call 264 * dvmInitAfterZygote(). 265 * checkjni 266 * If set, make sure "check JNI" is eabled. This is a little weird, 267 * because we already have the JNIEnv for the main thread set up. However, 268 * since we only have one thread at this point, it's easy to patch up. 269 * assert 270 * If set, make sure assertions are enabled. This gets fairly weird, 271 * because it affects the result of a method called by class initializers, 272 * and hence can't affect pre-loaded/initialized classes. 273 * safemode 274 * If set, operates the VM in the safe mode. The definition of "safe mode" is 275 * implementation dependent and currently only the JIT compiler is disabled. 276 * This is easy to handle because the compiler thread and associated resources 277 * are not requested until we call dvmInitAfterZygote(). 278 */ 279 static void enableDebugFeatures(u4 debugFlags) 280 { 281 LOGV("debugFlags is 0x%02x\n", debugFlags); 282 283 gDvm.jdwpAllowed = ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0); 284 285 if ((debugFlags & DEBUG_ENABLE_CHECKJNI) != 0) { 286 /* turn it on if it's not already enabled */ 287 dvmLateEnableCheckedJni(); 288 } 289 290 if ((debugFlags & DEBUG_ENABLE_ASSERT) != 0) { 291 /* turn it on if it's not already enabled */ 292 dvmLateEnableAssertions(); 293 } 294 295 if ((debugFlags & DEBUG_ENABLE_SAFEMODE) != 0) { 296 #if defined(WITH_JIT) 297 /* turn off the jit if it is explicitly requested by the app */ 298 if (gDvm.executionMode == kExecutionModeJit) 299 gDvm.executionMode = kExecutionModeInterpFast; 300 #endif 301 } 302 303 #if HAVE_ANDROID_OS 304 if ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0) { 305 /* To let a non-privileged gdbserver attach to this 306 * process, we must set its dumpable bit flag. However 307 * we are not interested in generating a coredump in 308 * case of a crash, so also set the coredump size to 0 309 * to disable that 310 */ 311 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { 312 LOGE("could not set dumpable bit flag for pid %d, errno=%d", 313 getpid(), errno); 314 } else { 315 struct rlimit rl; 316 rl.rlim_cur = 0; 317 rl.rlim_max = RLIM_INFINITY; 318 if (setrlimit(RLIMIT_CORE, &rl) < 0) { 319 LOGE("could not disable core file generation " 320 "for pid %d, errno=%d", getpid(), errno); 321 } 322 } 323 } 324 #endif 325 } 326 327 /* 328 * Utility routine to fork zygote and specialize the child process. 329 */ 330 static pid_t forkAndSpecializeCommon(const u4* args) 331 { 332 pid_t pid; 333 334 uid_t uid = (uid_t) args[0]; 335 gid_t gid = (gid_t) args[1]; 336 ArrayObject* gids = (ArrayObject *)args[2]; 337 u4 debugFlags = args[3]; 338 ArrayObject *rlimits = (ArrayObject *)args[4]; 339 340 if (!gDvm.zygote) { 341 dvmThrowException("Ljava/lang/IllegalStateException;", 342 "VM instance not started with -Xzygote"); 343 344 return -1; 345 } 346 347 if (!dvmGcPreZygoteFork()) { 348 LOGE("pre-fork heap failed\n"); 349 dvmAbort(); 350 } 351 352 setSignalHandler(); 353 354 dvmDumpLoaderStats("zygote"); 355 pid = fork(); 356 357 if (pid == 0) { 358 int err; 359 /* The child process */ 360 361 #ifdef HAVE_ANDROID_OS 362 extern int gMallocLeakZygoteChild; 363 gMallocLeakZygoteChild = 1; 364 365 /* keep caps across UID change, unless we're staying root */ 366 if (uid != 0) { 367 err = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); 368 369 if (err < 0) { 370 LOGW("cannot PR_SET_KEEPCAPS errno: %d", errno); 371 } 372 } 373 374 #endif /* HAVE_ANDROID_OS */ 375 376 err = setgroupsIntarray(gids); 377 378 if (err < 0) { 379 LOGW("cannot setgroups() errno: %d", errno); 380 } 381 382 err = setrlimitsFromArray(rlimits); 383 384 if (err < 0) { 385 LOGW("cannot setrlimit() errno: %d", errno); 386 } 387 388 err = setgid(gid); 389 if (err < 0) { 390 LOGW("cannot setgid(%d) errno: %d", gid, errno); 391 } 392 393 err = setuid(uid); 394 if (err < 0) { 395 LOGW("cannot setuid(%d) errno: %d", uid, errno); 396 } 397 398 /* 399 * Our system thread ID has changed. Get the new one. 400 */ 401 Thread* thread = dvmThreadSelf(); 402 thread->systemTid = dvmGetSysThreadId(); 403 404 /* configure additional debug options */ 405 enableDebugFeatures(debugFlags); 406 407 unsetSignalHandler(); 408 gDvm.zygote = false; 409 if (!dvmInitAfterZygote()) { 410 LOGE("error in post-zygote initialization\n"); 411 dvmAbort(); 412 } 413 } else if (pid > 0) { 414 /* the parent process */ 415 } 416 417 return pid; 418 } 419 420 /* native public static int forkAndSpecialize(int uid, int gid, 421 * int[] gids, int debugFlags); 422 */ 423 static void Dalvik_dalvik_system_Zygote_forkAndSpecialize(const u4* args, 424 JValue* pResult) 425 { 426 pid_t pid; 427 428 pid = forkAndSpecializeCommon(args); 429 430 RETURN_INT(pid); 431 } 432 433 /* native public static int forkSystemServer(int uid, int gid, 434 * int[] gids, int debugFlags); 435 */ 436 static void Dalvik_dalvik_system_Zygote_forkSystemServer( 437 const u4* args, JValue* pResult) 438 { 439 pid_t pid; 440 pid = forkAndSpecializeCommon(args); 441 442 /* The zygote process checks whether the child process has died or not. */ 443 if (pid > 0) { 444 int status; 445 446 LOGI("System server process %d has been created", pid); 447 gDvm.systemServerPid = pid; 448 /* There is a slight window that the system server process has crashed 449 * but it went unnoticed because we haven't published its pid yet. So 450 * we recheck here just to make sure that all is well. 451 */ 452 if (waitpid(pid, &status, WNOHANG) == pid) { 453 LOGE("System server process %d has died. Restarting Zygote!", pid); 454 kill(getpid(), SIGKILL); 455 } 456 } 457 RETURN_INT(pid); 458 } 459 460 const DalvikNativeMethod dvm_dalvik_system_Zygote[] = { 461 { "fork", "()I", 462 Dalvik_dalvik_system_Zygote_fork }, 463 { "forkAndSpecialize", "(II[II[[I)I", 464 Dalvik_dalvik_system_Zygote_forkAndSpecialize }, 465 { "forkSystemServer", "(II[II[[I)I", 466 Dalvik_dalvik_system_Zygote_forkSystemServer }, 467 { NULL, NULL, NULL }, 468 }; 469