diff options
-rw-r--r-- | vm/native/dalvik_system_Zygote.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/vm/native/dalvik_system_Zygote.cpp b/vm/native/dalvik_system_Zygote.cpp index 1bcaac5c7..e892378cf 100644 --- a/vm/native/dalvik_system_Zygote.cpp +++ b/vm/native/dalvik_system_Zygote.cpp @@ -677,6 +677,23 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l dvmDumpLoaderStats("zygote"); + sigset_t sigchld; + sigemptyset(&sigchld); + sigaddset(&sigchld, SIGCHLD); + + // Temporarily block SIGCHLD during forks. The SIGCHLD handler might + // log, which would result in the logging FDs we close being + // reopened. + // This would cause failures because the FDs are not whitelisted. + // + // Note that the zygote process is single threaded at this + // point. + if (sigprocmask(SIG_BLOCK, &sigchld, NULL) == -1) { + ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)); + dvmAbort(); + } + + // Close any logging related FDs before we start evaluating the list of // file descriptors. __android_log_close(); @@ -742,6 +759,11 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l ALOGE("Unable to reopen whitelisted descriptors."); dvmAbort(); } + + if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) { + ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)); + dvmAbort(); + } #endif /* HAVE_ANDROID_OS */ if (mountMode != MOUNT_EXTERNAL_NONE) { @@ -844,6 +866,13 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l /* the parent process */ free(seInfo); free(niceName); + + // We blocked SIGCHLD prior to a fork, we unblock it here. + if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) { + ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)); + dvmAbort(); + } + } return pid; |