Zygote : Block SIGCHLD during fork.
am: b1f1209d9a
Change-Id: I3658f583c82dd6243089aaa74ad731a5bfa85b01
This commit is contained in:
@@ -446,6 +446,20 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
|
||||
ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler");
|
||||
|
||||
|
||||
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();
|
||||
@@ -479,6 +493,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);
|
||||
@@ -613,6 +632,12 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
|
||||
}
|
||||
} else if (pid > 0) {
|
||||
// the parent process
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user