Zygote : Block SIGCHLD during fork.

am: dfcc79ee8e

Change-Id: I64b380e54d73c777898ece33ba62b838b556921b
This commit is contained in:
Narayan Kamath
2016-11-10 10:15:56 +00:00
committed by android-build-merger

View File

@@ -454,6 +454,20 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
SetForkLoad(true); SetForkLoad(true);
#endif #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, nullptr) == -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 // Close any logging related FDs before we start evaluating the list of
// file descriptors. // file descriptors.
__android_log_close(); __android_log_close();
@@ -485,6 +499,11 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
RuntimeAbort(env, __LINE__, "Unable to reopen whitelisted descriptors."); RuntimeAbort(env, __LINE__, "Unable to reopen whitelisted descriptors.");
} }
if (sigprocmask(SIG_UNBLOCK, &sigchld, nullptr) == -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. // Keep capabilities across UID change, unless we're staying root.
if (uid != 0) { if (uid != 0) {
EnableKeepCapabilities(env); EnableKeepCapabilities(env);
@@ -618,6 +637,11 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
SetForkLoad(false); SetForkLoad(false);
#endif #endif
// We blocked SIGCHLD prior to a fork, we unblock it here.
if (sigprocmask(SIG_UNBLOCK, &sigchld, nullptr) == -1) {
ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));
RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_UNBLOCK, { SIGCHLD }) failed.");
}
} }
return pid; return pid;
} }