Zygote : Block SIGCHLD during fork.
am: dfcc79ee8e
Change-Id: I64b380e54d73c777898ece33ba62b838b556921b
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user