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 #include <paths.h> 29 #include <sys/personality.h> 30 #include <cutils/sched_policy.h> 31 32 #if defined(HAVE_PRCTL) 33 # include <sys/prctl.h> 34 #endif 35 36 #define ZYGOTE_LOG_TAG "Zygote" 37 38 /* must match values in dalvik.system.Zygote */ 39 enum { 40 DEBUG_ENABLE_DEBUGGER = 1, 41 DEBUG_ENABLE_CHECKJNI = 1 << 1, 42 DEBUG_ENABLE_ASSERT = 1 << 2, 43 DEBUG_ENABLE_SAFEMODE = 1 << 3, 44 DEBUG_ENABLE_JNI_LOGGING = 1 << 4, 45 }; 46 47 /* 48 * This signal handler is for zygote mode, since the zygote 49 * must reap its children 50 */ 51 static void sigchldHandler(int s) 52 { 53 pid_t pid; 54 int status; 55 56 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 57 /* Log process-death status that we care about. In general it is not 58 safe to call ALOG(...) from a signal handler because of possible 59 reentrancy. However, we know a priori that the current implementation 60 of ALOG() is safe to call from a SIGCHLD handler in the zygote process. 61 If the ALOG() implementation changes its locking strategy or its use 62 of syscalls within the lazy-init critical section, its use here may 63 become unsafe. */ 64 if (WIFEXITED(status)) { 65 if (WEXITSTATUS(status)) { 66 ALOG(LOG_DEBUG, ZYGOTE_LOG_TAG, "Process %d exited cleanly (%d)", 67 (int) pid, WEXITSTATUS(status)); 68 } else { 69 IF_ALOGV(/*should use ZYGOTE_LOG_TAG*/) { 70 ALOG(LOG_VERBOSE, ZYGOTE_LOG_TAG, 71 "Process %d exited cleanly (%d)", 72 (int) pid, WEXITSTATUS(status)); 73 } 74 } 75 } else if (WIFSIGNALED(status)) { 76 if (WTERMSIG(status) != SIGKILL) { 77 ALOG(LOG_DEBUG, ZYGOTE_LOG_TAG, 78 "Process %d terminated by signal (%d)", 79 (int) pid, WTERMSIG(status)); 80 } else { 81 IF_ALOGV(/*should use ZYGOTE_LOG_TAG*/) { 82 ALOG(LOG_VERBOSE, ZYGOTE_LOG_TAG, 83 "Process %d terminated by signal (%d)", 84 (int) pid, WTERMSIG(status)); 85 } 86 } 87 #ifdef WCOREDUMP 88 if (WCOREDUMP(status)) { 89 ALOG(LOG_INFO, ZYGOTE_LOG_TAG, "Process %d dumped core", 90 (int) pid); 91 } 92 #endif /* ifdef WCOREDUMP */ 93 } 94 95 /* 96 * If the just-crashed process is the system_server, bring down zygote 97 * so that it is restarted by init and system server will be restarted 98 * from there. 99 */ 100 if (pid == gDvm.systemServerPid) { 101 ALOG(LOG_INFO, ZYGOTE_LOG_TAG, 102 "Exit zygote because system server (%d) has terminated", 103 (int) pid); 104 kill(getpid(), SIGKILL); 105 } 106 } 107 108 if (pid < 0) { 109 ALOG(LOG_WARN, ZYGOTE_LOG_TAG, 110 "Zygote SIGCHLD error in waitpid: %s",strerror(errno)); 111 } 112 } 113 114 /* 115 * configure sigchld handler for the zygote process 116 * This is configured very late, because earlier in the dalvik lifecycle 117 * we can fork() and exec() for the verifier/optimizer, and we 118 * want to waitpid() for those rather than have them be harvested immediately. 119 * 120 * This ends up being called repeatedly before each fork(), but there's 121 * no real harm in that. 122 */ 123 static void setSignalHandler() 124 { 125 int err; 126 struct sigaction sa; 127 128 memset(&sa, 0, sizeof(sa)); 129 130 sa.sa_handler = sigchldHandler; 131 132 err = sigaction (SIGCHLD, &sa, NULL); 133 134 if (err < 0) { 135 ALOGW("Error setting SIGCHLD handler: %s", strerror(errno)); 136 } 137 } 138 139 /* 140 * Set the SIGCHLD handler back to default behavior in zygote children 141 */ 142 static void unsetSignalHandler() 143 { 144 int err; 145 struct sigaction sa; 146 147 memset(&sa, 0, sizeof(sa)); 148 149 sa.sa_handler = SIG_DFL; 150 151 err = sigaction (SIGCHLD, &sa, NULL); 152 153 if (err < 0) { 154 ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno)); 155 } 156 } 157 158 /* 159 * Calls POSIX setgroups() using the int[] object as an argument. 160 * A NULL argument is tolerated. 161 */ 162 163 static int setgroupsIntarray(ArrayObject* gidArray) 164 { 165 gid_t *gids; 166 u4 i; 167 s4 *contents; 168 169 if (gidArray == NULL) { 170 return 0; 171 } 172 173 /* just in case gid_t and u4 are different... */ 174 gids = (gid_t *)alloca(sizeof(gid_t) * gidArray->length); 175 contents = (s4 *)(void *)gidArray->contents; 176 177 for (i = 0 ; i < gidArray->length ; i++) { 178 gids[i] = (gid_t) contents[i]; 179 } 180 181 return setgroups((size_t) gidArray->length, gids); 182 } 183 184 /* 185 * Sets the resource limits via setrlimit(2) for the values in the 186 * two-dimensional array of integers that's passed in. The second dimension 187 * contains a tuple of length 3: (resource, rlim_cur, rlim_max). NULL is 188 * treated as an empty array. 189 * 190 * -1 is returned on error. 191 */ 192 static int setrlimitsFromArray(ArrayObject* rlimits) 193 { 194 u4 i; 195 struct rlimit rlim; 196 197 if (rlimits == NULL) { 198 return 0; 199 } 200 201 memset (&rlim, 0, sizeof(rlim)); 202 203 ArrayObject** tuples = (ArrayObject **)(void *)rlimits->contents; 204 205 for (i = 0; i < rlimits->length; i++) { 206 ArrayObject * rlimit_tuple = tuples[i]; 207 s4* contents = (s4 *)(void *)rlimit_tuple->contents; 208 int err; 209 210 if (rlimit_tuple->length != 3) { 211 ALOGE("rlimits array must have a second dimension of size 3"); 212 return -1; 213 } 214 215 rlim.rlim_cur = contents[1]; 216 rlim.rlim_max = contents[2]; 217 218 err = setrlimit(contents[0], &rlim); 219 220 if (err < 0) { 221 return -1; 222 } 223 } 224 225 return 0; 226 } 227 228 /* native public static int fork(); */ 229 static void Dalvik_dalvik_system_Zygote_fork(const u4* args, JValue* pResult) 230 { 231 pid_t pid; 232 233 if (!gDvm.zygote) { 234 dvmThrowIllegalStateException( 235 "VM instance not started with -Xzygote"); 236 237 RETURN_VOID(); 238 } 239 240 if (!dvmGcPreZygoteFork()) { 241 ALOGE("pre-fork heap failed"); 242 dvmAbort(); 243 } 244 245 setSignalHandler(); 246 247 dvmDumpLoaderStats("zygote"); 248 pid = fork(); 249 250 #ifdef HAVE_ANDROID_OS 251 if (pid == 0) { 252 /* child process */ 253 extern int gMallocLeakZygoteChild; 254 gMallocLeakZygoteChild = 1; 255 } 256 #endif 257 258 RETURN_INT(pid); 259 } 260 261 /* 262 * Enable/disable debug features requested by the caller. 263 * 264 * debugger 265 * If set, enable debugging; if not set, disable debugging. This is 266 * easy to handle, because the JDWP thread isn't started until we call 267 * dvmInitAfterZygote(). 268 * checkjni 269 * If set, make sure "check JNI" is enabled. 270 * assert 271 * If set, make sure assertions are enabled. This gets fairly weird, 272 * because it affects the result of a method called by class initializers, 273 * and hence can't affect pre-loaded/initialized classes. 274 * safemode 275 * If set, operates the VM in the safe mode. The definition of "safe mode" is 276 * implementation dependent and currently only the JIT compiler is disabled. 277 * This is easy to handle because the compiler thread and associated resources 278 * are not requested until we call dvmInitAfterZygote(). 279 */ 280 static void enableDebugFeatures(u4 debugFlags) 281 { 282 ALOGV("debugFlags is 0x%02x", debugFlags); 283 284 gDvm.jdwpAllowed = ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0); 285 286 if ((debugFlags & DEBUG_ENABLE_CHECKJNI) != 0) { 287 /* turn it on if it's not already enabled */ 288 dvmLateEnableCheckedJni(); 289 } 290 291 if ((debugFlags & DEBUG_ENABLE_JNI_LOGGING) != 0) { 292 gDvmJni.logThirdPartyJni = true; 293 } 294 295 if ((debugFlags & DEBUG_ENABLE_ASSERT) != 0) { 296 /* turn it on if it's not already enabled */ 297 dvmLateEnableAssertions(); 298 } 299 300 if ((debugFlags & DEBUG_ENABLE_SAFEMODE) != 0) { 301 #if defined(WITH_JIT) 302 /* turn off the jit if it is explicitly requested by the app */ 303 if (gDvm.executionMode == kExecutionModeJit) 304 gDvm.executionMode = kExecutionModeInterpFast; 305 #endif 306 } 307 308 #ifdef HAVE_ANDROID_OS 309 if ((debugFlags & DEBUG_ENABLE_DEBUGGER) != 0) { 310 /* To let a non-privileged gdbserver attach to this 311 * process, we must set its dumpable bit flag. However 312 * we are not interested in generating a coredump in 313 * case of a crash, so also set the coredump size to 0 314 * to disable that 315 */ 316 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { 317 ALOGE("could not set dumpable bit flag for pid %d: %s", 318 getpid(), strerror(errno)); 319 } else { 320 struct rlimit rl; 321 rl.rlim_cur = 0; 322 rl.rlim_max = RLIM_INFINITY; 323 if (setrlimit(RLIMIT_CORE, &rl) < 0) { 324 ALOGE("could not disable core file generation for pid %d: %s", 325 getpid(), strerror(errno)); 326 } 327 } 328 } 329 #endif 330 } 331 332 /* 333 * Set Linux capability flags. 334 * 335 * Returns 0 on success, errno on failure. 336 */ 337 static int setCapabilities(int64_t permitted, int64_t effective) 338 { 339 #ifdef HAVE_ANDROID_OS 340 struct __user_cap_header_struct capheader; 341 struct __user_cap_data_struct capdata; 342 343 memset(&capheader, 0, sizeof(capheader)); 344 memset(&capdata, 0, sizeof(capdata)); 345 346 capheader.version = _LINUX_CAPABILITY_VERSION; 347 capheader.pid = 0; 348 349 capdata.effective = effective; 350 capdata.permitted = permitted; 351 352 ALOGV("CAPSET perm=%llx eff=%llx", permitted, effective); 353 if (capset(&capheader, &capdata) != 0) 354 return errno; 355 #endif /*HAVE_ANDROID_OS*/ 356 357 return 0; 358 } 359 360 /* 361 * Utility routine to fork zygote and specialize the child process. 362 */ 363 static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer) 364 { 365 pid_t pid; 366 367 uid_t uid = (uid_t) args[0]; 368 gid_t gid = (gid_t) args[1]; 369 ArrayObject* gids = (ArrayObject *)args[2]; 370 u4 debugFlags = args[3]; 371 ArrayObject *rlimits = (ArrayObject *)args[4]; 372 int64_t permittedCapabilities, effectiveCapabilities; 373 374 if (isSystemServer) { 375 /* 376 * Don't use GET_ARG_LONG here for now. gcc is generating code 377 * that uses register d8 as a temporary, and that's coming out 378 * scrambled in the child process. b/3138621 379 */ 380 //permittedCapabilities = GET_ARG_LONG(args, 5); 381 //effectiveCapabilities = GET_ARG_LONG(args, 7); 382 permittedCapabilities = args[5] | (int64_t) args[6] << 32; 383 effectiveCapabilities = args[7] | (int64_t) args[8] << 32; 384 } else { 385 permittedCapabilities = effectiveCapabilities = 0; 386 } 387 388 if (!gDvm.zygote) { 389 dvmThrowIllegalStateException( 390 "VM instance not started with -Xzygote"); 391 392 return -1; 393 } 394 395 if (!dvmGcPreZygoteFork()) { 396 ALOGE("pre-fork heap failed"); 397 dvmAbort(); 398 } 399 400 setSignalHandler(); 401 402 dvmDumpLoaderStats("zygote"); 403 pid = fork(); 404 405 if (pid == 0) { 406 int err; 407 /* The child process */ 408 409 #ifdef HAVE_ANDROID_OS 410 extern int gMallocLeakZygoteChild; 411 gMallocLeakZygoteChild = 1; 412 413 /* keep caps across UID change, unless we're staying root */ 414 if (uid != 0) { 415 err = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); 416 417 if (err < 0) { 418 ALOGE("cannot PR_SET_KEEPCAPS: %s", strerror(errno)); 419 dvmAbort(); 420 } 421 } 422 423 #endif /* HAVE_ANDROID_OS */ 424 425 err = setgroupsIntarray(gids); 426 427 if (err < 0) { 428 ALOGE("cannot setgroups(): %s", strerror(errno)); 429 dvmAbort(); 430 } 431 432 err = setrlimitsFromArray(rlimits); 433 434 if (err < 0) { 435 ALOGE("cannot setrlimit(): %s", strerror(errno)); 436 dvmAbort(); 437 } 438 439 err = setgid(gid); 440 if (err < 0) { 441 ALOGE("cannot setgid(%d): %s", gid, strerror(errno)); 442 dvmAbort(); 443 } 444 445 err = setuid(uid); 446 if (err < 0) { 447 ALOGE("cannot setuid(%d): %s", uid, strerror(errno)); 448 dvmAbort(); 449 } 450 451 int current = personality(0xffffFFFF); 452 int success = personality((ADDR_NO_RANDOMIZE | current)); 453 if (success == -1) { 454 ALOGW("Personality switch failed. current=%d error=%d\n", current, errno); 455 } 456 457 err = setCapabilities(permittedCapabilities, effectiveCapabilities); 458 if (err != 0) { 459 ALOGE("cannot set capabilities (%llx,%llx): %s", 460 permittedCapabilities, effectiveCapabilities, strerror(err)); 461 dvmAbort(); 462 } 463 464 err = set_sched_policy(0, SP_DEFAULT); 465 if (err < 0) { 466 ALOGE("cannot set_sched_policy(0, SP_DEFAULT): %s", strerror(-err)); 467 dvmAbort(); 468 } 469 470 /* 471 * Our system thread ID has changed. Get the new one. 472 */ 473 Thread* thread = dvmThreadSelf(); 474 thread->systemTid = dvmGetSysThreadId(); 475 476 /* configure additional debug options */ 477 enableDebugFeatures(debugFlags); 478 479 unsetSignalHandler(); 480 gDvm.zygote = false; 481 if (!dvmInitAfterZygote()) { 482 ALOGE("error in post-zygote initialization"); 483 dvmAbort(); 484 } 485 } else if (pid > 0) { 486 /* the parent process */ 487 } 488 489 return pid; 490 } 491 492 /* native public static int forkAndSpecialize(int uid, int gid, 493 * int[] gids, int debugFlags); 494 */ 495 static void Dalvik_dalvik_system_Zygote_forkAndSpecialize(const u4* args, 496 JValue* pResult) 497 { 498 pid_t pid; 499 500 pid = forkAndSpecializeCommon(args, false); 501 502 RETURN_INT(pid); 503 } 504 505 /* native public static int forkSystemServer(int uid, int gid, 506 * int[] gids, int debugFlags, long permittedCapabilities, 507 * long effectiveCapabilities); 508 */ 509 static void Dalvik_dalvik_system_Zygote_forkSystemServer( 510 const u4* args, JValue* pResult) 511 { 512 pid_t pid; 513 pid = forkAndSpecializeCommon(args, true); 514 515 /* The zygote process checks whether the child process has died or not. */ 516 if (pid > 0) { 517 int status; 518 519 ALOGI("System server process %d has been created", pid); 520 gDvm.systemServerPid = pid; 521 /* There is a slight window that the system server process has crashed 522 * but it went unnoticed because we haven't published its pid yet. So 523 * we recheck here just to make sure that all is well. 524 */ 525 if (waitpid(pid, &status, WNOHANG) == pid) { 526 ALOGE("System server process %d has died. Restarting Zygote!", pid); 527 kill(getpid(), SIGKILL); 528 } 529 } 530 RETURN_INT(pid); 531 } 532 533 /* native private static void nativeExecShell(String command); 534 */ 535 static void Dalvik_dalvik_system_Zygote_execShell( 536 const u4* args, JValue* pResult) 537 { 538 StringObject* command = (StringObject*)args[0]; 539 540 const char *argp[] = {_PATH_BSHELL, "-c", NULL, NULL}; 541 argp[2] = dvmCreateCstrFromString(command); 542 543 ALOGI("Exec: %s %s %s", argp[0], argp[1], argp[2]); 544 545 execv(_PATH_BSHELL, (char**)argp); 546 exit(127); 547 } 548 549 const DalvikNativeMethod dvm_dalvik_system_Zygote[] = { 550 { "nativeFork", "()I", 551 Dalvik_dalvik_system_Zygote_fork }, 552 { "nativeForkAndSpecialize", "(II[II[[I)I", 553 Dalvik_dalvik_system_Zygote_forkAndSpecialize }, 554 { "nativeForkSystemServer", "(II[II[[IJJ)I", 555 Dalvik_dalvik_system_Zygote_forkSystemServer }, 556 { "nativeExecShell", "(Ljava/lang/String;)V", 557 Dalvik_dalvik_system_Zygote_execShell }, 558 { NULL, NULL, NULL }, 559 }; 560