Skip to content

Commit c113e5e

Browse files
narayankandi34
authored andcommitted
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 (cherry picked from commit e9a525829a354c92983a35455ccab16d1b0d3892) Also contains a port of commit c7161f756e86b98f2244a04d9207b. Change-Id: I27dc83218df592ace8bff2942e8d94dcd5d61931
1 parent 3c26944 commit c113e5e

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

vm/native/dalvik_system_Zygote.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,23 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l
600600

601601
dvmDumpLoaderStats("zygote");
602602

603+
sigset_t sigchld;
604+
sigemptyset(&sigchld);
605+
sigaddset(&sigchld, SIGCHLD);
606+
607+
// Temporarily block SIGCHLD during forks. The SIGCHLD handler might
608+
// log, which would result in the logging FDs we close being
609+
// reopened.
610+
// This would cause failures because the FDs are not whitelisted.
611+
//
612+
// Note that the zygote process is single threaded at this
613+
// point.
614+
if (sigprocmask(SIG_BLOCK, &sigchld, NULL) == -1) {
615+
ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));
616+
dvmAbort();
617+
}
618+
619+
603620
// Close any logging related FDs before we start evaluating the list of
604621
// file descriptors.
605622
__android_log_close();
@@ -665,6 +682,11 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l
665682
ALOGE("Unable to reopen whitelisted descriptors.");
666683
dvmAbort();
667684
}
685+
686+
if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) {
687+
ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));
688+
dvmAbort();
689+
}
668690
#endif /* HAVE_ANDROID_OS */
669691

670692
if (mountMode != MOUNT_EXTERNAL_NONE) {
@@ -759,6 +781,13 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l
759781
/* the parent process */
760782
free(seInfo);
761783
free(niceName);
784+
785+
// We blocked SIGCHLD prior to a fork, we unblock it here.
786+
if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) {
787+
ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));
788+
dvmAbort();
789+
}
790+
762791
}
763792

764793
return pid;

0 commit comments

Comments
 (0)