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 // sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc 18 #include <sys/mount.h> 19 #include <linux/fs.h> 20 21 #include <grp.h> 22 #include <paths.h> 23 #include <signal.h> 24 #include <stdlib.h> 25 #include <sys/types.h> 26 #include <sys/wait.h> 27 #include <unistd.h> 28 29 #include "cutils/fs.h" 30 #include "cutils/multiuser.h" 31 #include "cutils/sched_policy.h" 32 #include "debugger.h" 33 #include "jni_internal.h" 34 #include "JNIHelp.h" 35 #include "ScopedLocalRef.h" 36 #include "ScopedPrimitiveArray.h" 37 #include "ScopedUtfChars.h" 38 #include "thread.h" 39 40 #if defined(HAVE_PRCTL) 41 #include <sys/prctl.h> 42 #endif 43 44 #include <selinux/android.h> 45 46 #if defined(__linux__) 47 #include <sys/personality.h> 48 #include <sys/utsname.h> 49 #include <sys/capability.h> 50 #endif 51 52 namespace art { 53 54 static pid_t gSystemServerPid = 0; 55 56 // Must match values in dalvik.system.Zygote. 57 enum MountExternalKind { 58 MOUNT_EXTERNAL_NONE = 0, 59 MOUNT_EXTERNAL_SINGLEUSER = 1, 60 MOUNT_EXTERNAL_MULTIUSER = 2, 61 MOUNT_EXTERNAL_MULTIUSER_ALL = 3, 62 }; 63 64 // This signal handler is for zygote mode, since the zygote must reap its children 65 static void SigChldHandler(int /*signal_number*/) { 66 pid_t pid; 67 int status; 68 69 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 70 // Log process-death status that we care about. In general it is 71 // not safe to call LOG(...) from a signal handler because of 72 // possible reentrancy. However, we know a priori that the 73 // current implementation of LOG() is safe to call from a SIGCHLD 74 // handler in the zygote process. If the LOG() implementation 75 // changes its locking strategy or its use of syscalls within the 76 // lazy-init critical section, its use here may become unsafe. 77 if (WIFEXITED(status)) { 78 if (WEXITSTATUS(status)) { 79 LOG(INFO) << "Process " << pid << " exited cleanly (" << WEXITSTATUS(status) << ")"; 80 } else if (false) { 81 LOG(INFO) << "Process " << pid << " exited cleanly (" << WEXITSTATUS(status) << ")"; 82 } 83 } else if (WIFSIGNALED(status)) { 84 if (WTERMSIG(status) != SIGKILL) { 85 LOG(INFO) << "Process " << pid << " terminated by signal (" << WTERMSIG(status) << ")"; 86 } else if (false) { 87 LOG(INFO) << "Process " << pid << " terminated by signal (" << WTERMSIG(status) << ")"; 88 } 89 #ifdef WCOREDUMP 90 if (WCOREDUMP(status)) { 91 LOG(INFO) << "Process " << pid << " dumped core"; 92 } 93 #endif /* ifdef WCOREDUMP */ 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 if (pid == gSystemServerPid) { 100 LOG(ERROR) << "Exit zygote because system server (" << pid << ") has terminated"; 101 kill(getpid(), SIGKILL); 102 } 103 } 104 105 if (pid < 0) { 106 PLOG(WARNING) << "Zygote SIGCHLD error in waitpid"; 107 } 108 } 109 110 // Configures the SIGCHLD handler for the zygote process. This is configured 111 // very late, because earlier in the runtime we may fork() and exec() 112 // other processes, and we want to waitpid() for those rather than 113 // have them be harvested immediately. 114 // 115 // This ends up being called repeatedly before each fork(), but there's 116 // no real harm in that. 117 static void SetSigChldHandler() { 118 struct sigaction sa; 119 memset(&sa, 0, sizeof(sa)); 120 sa.sa_handler = SigChldHandler; 121 122 int err = sigaction(SIGCHLD, &sa, NULL); 123 if (err < 0) { 124 PLOG(WARNING) << "Error setting SIGCHLD handler"; 125 } 126 } 127 128 // Sets the SIGCHLD handler back to default behavior in zygote children. 129 static void UnsetSigChldHandler() { 130 struct sigaction sa; 131 memset(&sa, 0, sizeof(sa)); 132 sa.sa_handler = SIG_DFL; 133 134 int err = sigaction(SIGCHLD, &sa, NULL); 135 if (err < 0) { 136 PLOG(WARNING) << "Error unsetting SIGCHLD handler"; 137 } 138 } 139 140 // Calls POSIX setgroups() using the int[] object as an argument. 141 // A NULL argument is tolerated. 142 static void SetGids(JNIEnv* env, jintArray javaGids) { 143 if (javaGids == NULL) { 144 return; 145 } 146 147 COMPILE_ASSERT(sizeof(gid_t) == sizeof(jint), sizeof_gid_and_jint_are_differerent); 148 ScopedIntArrayRO gids(env, javaGids); 149 CHECK(gids.get() != NULL); 150 int rc = setgroups(gids.size(), reinterpret_cast<const gid_t*>(&gids[0])); 151 if (rc == -1) { 152 PLOG(FATAL) << "setgroups failed"; 153 } 154 } 155 156 // Sets the resource limits via setrlimit(2) for the values in the 157 // two-dimensional array of integers that's passed in. The second dimension 158 // contains a tuple of length 3: (resource, rlim_cur, rlim_max). NULL is 159 // treated as an empty array. 160 static void SetRLimits(JNIEnv* env, jobjectArray javaRlimits) { 161 if (javaRlimits == NULL) { 162 return; 163 } 164 165 rlimit rlim; 166 memset(&rlim, 0, sizeof(rlim)); 167 168 for (int i = 0; i < env->GetArrayLength(javaRlimits); ++i) { 169 ScopedLocalRef<jobject> javaRlimitObject(env, env->GetObjectArrayElement(javaRlimits, i)); 170 ScopedIntArrayRO javaRlimit(env, reinterpret_cast<jintArray>(javaRlimitObject.get())); 171 if (javaRlimit.size() != 3) { 172 LOG(FATAL) << "rlimits array must have a second dimension of size 3"; 173 } 174 175 rlim.rlim_cur = javaRlimit[1]; 176 rlim.rlim_max = javaRlimit[2]; 177 178 int rc = setrlimit(javaRlimit[0], &rlim); 179 if (rc == -1) { 180 PLOG(FATAL) << "setrlimit(" << javaRlimit[0] << ", " 181 << "{" << rlim.rlim_cur << ", " << rlim.rlim_max << "}) failed"; 182 } 183 } 184 } 185 186 #if defined(HAVE_ANDROID_OS) 187 188 // The debug malloc library needs to know whether it's the zygote or a child. 189 extern "C" int gMallocLeakZygoteChild; 190 191 static void EnableDebugger() { 192 // To let a non-privileged gdbserver attach to this 193 // process, we must set our dumpable flag. 194 if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { 195 PLOG(ERROR) << "prctl(PR_SET_DUMPABLE) failed for pid " << getpid(); 196 } 197 // We don't want core dumps, though, so set the core dump size to 0. 198 rlimit rl; 199 rl.rlim_cur = 0; 200 rl.rlim_max = RLIM_INFINITY; 201 if (setrlimit(RLIMIT_CORE, &rl) == -1) { 202 PLOG(ERROR) << "setrlimit(RLIMIT_CORE) failed for pid " << getpid(); 203 } 204 } 205 206 static void EnableKeepCapabilities() { 207 int rc = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); 208 if (rc == -1) { 209 PLOG(FATAL) << "prctl(PR_SET_KEEPCAPS) failed"; 210 } 211 } 212 213 static void DropCapabilitiesBoundingSet() { 214 for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) { 215 if (i == CAP_NET_RAW) { 216 // Don't break /system/bin/ping 217 continue; 218 } 219 int rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); 220 if (rc == -1) { 221 if (errno == EINVAL) { 222 PLOG(ERROR) << "prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify " 223 << "your kernel is compiled with file capabilities support"; 224 } else { 225 PLOG(FATAL) << "prctl(PR_CAPBSET_DROP) failed"; 226 } 227 } 228 } 229 } 230 231 static void SetCapabilities(int64_t permitted, int64_t effective) { 232 __user_cap_header_struct capheader; 233 __user_cap_data_struct capdata; 234 235 memset(&capheader, 0, sizeof(capheader)); 236 memset(&capdata, 0, sizeof(capdata)); 237 238 capheader.version = _LINUX_CAPABILITY_VERSION; 239 capheader.pid = 0; 240 241 capdata.effective = effective; 242 capdata.permitted = permitted; 243 244 if (capset(&capheader, &capdata) != 0) { 245 PLOG(FATAL) << "capset(" << permitted << ", " << effective << ") failed"; 246 } 247 } 248 249 static void SetSchedulerPolicy() { 250 errno = -set_sched_policy(0, SP_DEFAULT); 251 if (errno != 0) { 252 PLOG(FATAL) << "set_sched_policy(0, SP_DEFAULT) failed"; 253 } 254 } 255 256 #else 257 258 static int gMallocLeakZygoteChild = 0; 259 260 static void EnableDebugger() {} 261 static void EnableKeepCapabilities() {} 262 static void DropCapabilitiesBoundingSet() {} 263 static void SetCapabilities(int64_t, int64_t) {} 264 static void SetSchedulerPolicy() {} 265 266 #endif 267 268 static void EnableDebugFeatures(uint32_t debug_flags) { 269 // Must match values in dalvik.system.Zygote. 270 enum { 271 DEBUG_ENABLE_DEBUGGER = 1, 272 DEBUG_ENABLE_CHECKJNI = 1 << 1, 273 DEBUG_ENABLE_ASSERT = 1 << 2, 274 DEBUG_ENABLE_SAFEMODE = 1 << 3, 275 DEBUG_ENABLE_JNI_LOGGING = 1 << 4, 276 }; 277 278 if ((debug_flags & DEBUG_ENABLE_CHECKJNI) != 0) { 279 Runtime* runtime = Runtime::Current(); 280 JavaVMExt* vm = runtime->GetJavaVM(); 281 if (!vm->check_jni) { 282 LOG(DEBUG) << "Late-enabling -Xcheck:jni"; 283 vm->SetCheckJniEnabled(true); 284 // There's only one thread running at this point, so only one JNIEnv to fix up. 285 Thread::Current()->GetJniEnv()->SetCheckJniEnabled(true); 286 } else { 287 LOG(DEBUG) << "Not late-enabling -Xcheck:jni (already on)"; 288 } 289 debug_flags &= ~DEBUG_ENABLE_CHECKJNI; 290 } 291 292 if ((debug_flags & DEBUG_ENABLE_JNI_LOGGING) != 0) { 293 gLogVerbosity.third_party_jni = true; 294 debug_flags &= ~DEBUG_ENABLE_JNI_LOGGING; 295 } 296 297 Dbg::SetJdwpAllowed((debug_flags & DEBUG_ENABLE_DEBUGGER) != 0); 298 if ((debug_flags & DEBUG_ENABLE_DEBUGGER) != 0) { 299 EnableDebugger(); 300 } 301 debug_flags &= ~DEBUG_ENABLE_DEBUGGER; 302 303 // These two are for backwards compatibility with Dalvik. 304 debug_flags &= ~DEBUG_ENABLE_ASSERT; 305 debug_flags &= ~DEBUG_ENABLE_SAFEMODE; 306 307 if (debug_flags != 0) { 308 LOG(ERROR) << StringPrintf("Unknown bits set in debug_flags: %#x", debug_flags); 309 } 310 } 311 312 // Create a private mount namespace and bind mount appropriate emulated 313 // storage for the given user. 314 static bool MountEmulatedStorage(uid_t uid, jint mount_mode) { 315 if (mount_mode == MOUNT_EXTERNAL_NONE) { 316 return true; 317 } 318 319 // See storage config details at http://source.android.com/tech/storage/ 320 userid_t user_id = multiuser_get_user_id(uid); 321 322 // Create a second private mount namespace for our process 323 if (unshare(CLONE_NEWNS) == -1) { 324 PLOG(WARNING) << "Failed to unshare()"; 325 return false; 326 } 327 328 // Create bind mounts to expose external storage 329 if (mount_mode == MOUNT_EXTERNAL_MULTIUSER || mount_mode == MOUNT_EXTERNAL_MULTIUSER_ALL) { 330 // These paths must already be created by init.rc 331 const char* source = getenv("EMULATED_STORAGE_SOURCE"); 332 const char* target = getenv("EMULATED_STORAGE_TARGET"); 333 const char* legacy = getenv("EXTERNAL_STORAGE"); 334 if (source == NULL || target == NULL || legacy == NULL) { 335 LOG(WARNING) << "Storage environment undefined; unable to provide external storage"; 336 return false; 337 } 338 339 // Prepare source paths 340 341 // /mnt/shell/emulated/0 342 std::string source_user(StringPrintf("%s/%d", source, user_id)); 343 // /storage/emulated/0 344 std::string target_user(StringPrintf("%s/%d", target, user_id)); 345 346 if (fs_prepare_dir(source_user.c_str(), 0000, 0, 0) == -1 347 || fs_prepare_dir(target_user.c_str(), 0000, 0, 0) == -1) { 348 return false; 349 } 350 351 if (mount_mode == MOUNT_EXTERNAL_MULTIUSER_ALL) { 352 // Mount entire external storage tree for all users 353 if (mount(source, target, NULL, MS_BIND, NULL) == -1) { 354 PLOG(WARNING) << "Failed to mount " << source << " to " << target; 355 return false; 356 } 357 } else { 358 // Only mount user-specific external storage 359 if (mount(source_user.c_str(), target_user.c_str(), NULL, MS_BIND, NULL) == -1) { 360 PLOG(WARNING) << "Failed to mount " << source_user << " to " << target_user; 361 return false; 362 } 363 } 364 365 if (fs_prepare_dir(legacy, 0000, 0, 0) == -1) { 366 return false; 367 } 368 369 // Finally, mount user-specific path into place for legacy users 370 if (mount(target_user.c_str(), legacy, NULL, MS_BIND | MS_REC, NULL) == -1) { 371 PLOG(WARNING) << "Failed to mount " << target_user << " to " << legacy; 372 return false; 373 } 374 } else { 375 LOG(WARNING) << "Mount mode " << mount_mode << " unsupported"; 376 return false; 377 } 378 379 return true; 380 } 381 382 #if defined(__linux__) 383 static bool NeedsNoRandomizeWorkaround() { 384 #if !defined(__arm__) 385 return false; 386 #else 387 int major; 388 int minor; 389 struct utsname uts; 390 if (uname(&uts) == -1) { 391 return false; 392 } 393 394 if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) { 395 return false; 396 } 397 398 // Kernels before 3.4.* need the workaround. 399 return (major < 3) || ((major == 3) && (minor < 4)); 400 #endif 401 } 402 #endif 403 404 // Utility routine to fork zygote and specialize the child process. 405 static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids, 406 jint debug_flags, jobjectArray javaRlimits, 407 jlong permittedCapabilities, jlong effectiveCapabilities, 408 jint mount_external, 409 jstring java_se_info, jstring java_se_name, bool is_system_server) { 410 Runtime* runtime = Runtime::Current(); 411 CHECK(runtime->IsZygote()) << "runtime instance not started with -Xzygote"; 412 if (!runtime->PreZygoteFork()) { 413 LOG(FATAL) << "pre-fork heap failed"; 414 } 415 416 SetSigChldHandler(); 417 418 // Grab thread before fork potentially makes Thread::pthread_key_self_ unusable. 419 Thread* self = Thread::Current(); 420 421 // dvmDumpLoaderStats("zygote"); // TODO: ? 422 pid_t pid = fork(); 423 424 if (pid == 0) { 425 // The child process. 426 gMallocLeakZygoteChild = 1; 427 428 // Keep capabilities across UID change, unless we're staying root. 429 if (uid != 0) { 430 EnableKeepCapabilities(); 431 } 432 433 DropCapabilitiesBoundingSet(); 434 435 if (!MountEmulatedStorage(uid, mount_external)) { 436 PLOG(WARNING) << "Failed to mount emulated storage"; 437 if (errno == ENOTCONN || errno == EROFS) { 438 // When device is actively encrypting, we get ENOTCONN here 439 // since FUSE was mounted before the framework restarted. 440 // When encrypted device is booting, we get EROFS since 441 // FUSE hasn't been created yet by init. 442 // In either case, continue without external storage. 443 } else { 444 LOG(FATAL) << "Cannot continue without emulated storage"; 445 } 446 } 447 448 SetGids(env, javaGids); 449 450 SetRLimits(env, javaRlimits); 451 452 int rc = setresgid(gid, gid, gid); 453 if (rc == -1) { 454 PLOG(FATAL) << "setresgid(" << gid << ") failed"; 455 } 456 457 rc = setresuid(uid, uid, uid); 458 if (rc == -1) { 459 PLOG(FATAL) << "setresuid(" << uid << ") failed"; 460 } 461 462 #if defined(__linux__) 463 if (NeedsNoRandomizeWorkaround()) { 464 // Work around ARM kernel ASLR lossage (http://b/5817320). 465 int old_personality = personality(0xffffffff); 466 int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE); 467 if (new_personality == -1) { 468 PLOG(WARNING) << "personality(" << new_personality << ") failed"; 469 } 470 } 471 #endif 472 473 SetCapabilities(permittedCapabilities, effectiveCapabilities); 474 475 SetSchedulerPolicy(); 476 477 #if defined(HAVE_ANDROID_OS) 478 { // NOLINT(whitespace/braces) 479 const char* se_info_c_str = NULL; 480 UniquePtr<ScopedUtfChars> se_info; 481 if (java_se_info != NULL) { 482 se_info.reset(new ScopedUtfChars(env, java_se_info)); 483 se_info_c_str = se_info->c_str(); 484 CHECK(se_info_c_str != NULL); 485 } 486 const char* se_name_c_str = NULL; 487 UniquePtr<ScopedUtfChars> se_name; 488 if (java_se_name != NULL) { 489 se_name.reset(new ScopedUtfChars(env, java_se_name)); 490 se_name_c_str = se_name->c_str(); 491 CHECK(se_name_c_str != NULL); 492 } 493 rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str); 494 if (rc == -1) { 495 PLOG(FATAL) << "selinux_android_setcontext(" << uid << ", " 496 << (is_system_server ? "true" : "false") << ", " 497 << "\"" << se_info_c_str << "\", \"" << se_name_c_str << "\") failed"; 498 } 499 } 500 #else 501 UNUSED(is_system_server); 502 UNUSED(java_se_info); 503 UNUSED(java_se_name); 504 #endif 505 506 // Our system thread ID, etc, has changed so reset Thread state. 507 self->InitAfterFork(); 508 509 EnableDebugFeatures(debug_flags); 510 511 UnsetSigChldHandler(); 512 runtime->DidForkFromZygote(); 513 } else if (pid > 0) { 514 // the parent process 515 } 516 return pid; 517 } 518 519 static jint Zygote_nativeForkAndSpecialize(JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, 520 jint debug_flags, jobjectArray rlimits, jint mount_external, 521 jstring se_info, jstring se_name) { 522 return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, 0, 0, mount_external, se_info, se_name, false); 523 } 524 525 static jint Zygote_nativeForkSystemServer(JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, 526 jint debug_flags, jobjectArray rlimits, 527 jlong permittedCapabilities, jlong effectiveCapabilities) { 528 pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, 529 debug_flags, rlimits, 530 permittedCapabilities, effectiveCapabilities, 531 MOUNT_EXTERNAL_NONE, NULL, NULL, true); 532 if (pid > 0) { 533 // The zygote process checks whether the child process has died or not. 534 LOG(INFO) << "System server process " << pid << " has been created"; 535 gSystemServerPid = pid; 536 // There is a slight window that the system server process has crashed 537 // but it went unnoticed because we haven't published its pid yet. So 538 // we recheck here just to make sure that all is well. 539 int status; 540 if (waitpid(pid, &status, WNOHANG) == pid) { 541 LOG(FATAL) << "System server process " << pid << " has died. Restarting Zygote!"; 542 } 543 } 544 return pid; 545 } 546 547 static JNINativeMethod gMethods[] = { 548 NATIVE_METHOD(Zygote, nativeForkAndSpecialize, "(II[II[[IILjava/lang/String;Ljava/lang/String;)I"), 549 NATIVE_METHOD(Zygote, nativeForkSystemServer, "(II[II[[IJJ)I"), 550 }; 551 552 void register_dalvik_system_Zygote(JNIEnv* env) { 553 REGISTER_NATIVE_METHODS("dalvik/system/Zygote"); 554 } 555 556 } // namespace art 557