diff options
author | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2017-02-11 22:45:01 +0100 |
---|---|---|
committer | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2017-02-11 22:45:01 +0100 |
commit | c65088b68e9bb0aa97768c536822c6b82cc86b6f (patch) | |
tree | 6f1f1189764a238d417ed7d2f742a56f78507ad9 /core/jni/com_android_internal_os_Zygote.cpp | |
parent | a57394a0be5e601c447a07786487bd4c34b0d899 (diff) | |
parent | 4ba10939b7c05e4cf44d053ee8fa37a703c19e9b (diff) | |
download | frameworks_base-c65088b68e9bb0aa97768c536822c6b82cc86b6f.zip frameworks_base-c65088b68e9bb0aa97768c536822c6b82cc86b6f.tar.gz frameworks_base-c65088b68e9bb0aa97768c536822c6b82cc86b6f.tar.bz2 |
Merge branch 'cm-13.0' of https://github.com/LineageOS/android_frameworks_base into replicant-6.0
Diffstat (limited to 'core/jni/com_android_internal_os_Zygote.cpp')
-rw-r--r-- | core/jni/com_android_internal_os_Zygote.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 4f90bd9..8686444 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -465,6 +465,20 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra SetForkLoad(true); #endif + 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)); + RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_BLOCK, { SIGCHLD }) failed."); + } + // Close any logging related FDs before we start evaluating the list of // file descriptors. __android_log_close(); @@ -496,6 +510,11 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra RuntimeAbort(env, __LINE__, "Unable to reopen whitelisted descriptors."); } + if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) { + ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)); + RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_UNBLOCK, { SIGCHLD }) failed."); + } + // Keep capabilities across UID change, unless we're staying root. if (uid != 0) { EnableKeepCapabilities(env); @@ -628,11 +647,11 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra } else if (pid > 0) { // the parent process -#ifdef ENABLE_SCHED_BOOST - // unset scheduler knob - SetForkLoad(false); -#endif - + // 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)); + RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_UNBLOCK, { SIGCHLD }) failed."); + } } return pid; } |