Zygote : Block SIGCHLD during fork.
We close the android logging related sockets prior as late as possible before every fork to avoid having to whitelist them. If one of the zygote's children dies after this point (but prior to the fork), we can end up reopening the logging sockets from the SIGCHLD signal handler. To prevent this from happening, block SIGCHLD during this critical section. Bug: 32693692 Test: Manual Change-Id: Ia4763a0bfd821a25b68aba3939cb0a6cbf248de0
This commit is contained in:
@@ -449,6 +449,20 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra
|
||||
jstring instructionSet, jstring dataDir) {
|
||||
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, 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
|
||||
// file descriptors.
|
||||
__android_log_close();
|
||||
@@ -482,6 +496,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, 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.
|
||||
if (uid != 0) {
|
||||
EnableKeepCapabilities(env);
|
||||
|
||||
Reference in New Issue
Block a user