summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2016-11-07 18:50:07 +0000
committerDang Duy Son <xpduyson@gmail.com>2017-03-15 12:50:11 +0000
commit0faa8480ed007541e41925c8de2297bab437a9ee (patch)
tree15124f62b1ce708c1d83f58e1cbc81002e788264
parent127ede922857a28a2e051ae40f86efedc3bbd6b1 (diff)
downloadandroid_dalvik-cm-11.0.tar.gz
android_dalvik-cm-11.0.tar.bz2
android_dalvik-cm-11.0.zip
Zygote : Block SIGCHLD during fork.cm-11.0
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
-rw-r--r--vm/native/dalvik_system_Zygote.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/vm/native/dalvik_system_Zygote.cpp b/vm/native/dalvik_system_Zygote.cpp
index 1bcaac5c7..e892378cf 100644
--- a/vm/native/dalvik_system_Zygote.cpp
+++ b/vm/native/dalvik_system_Zygote.cpp
@@ -677,6 +677,23 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l
dvmDumpLoaderStats("zygote");
+ 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));
+ dvmAbort();
+ }
+
+
// Close any logging related FDs before we start evaluating the list of
// file descriptors.
__android_log_close();
@@ -742,6 +759,11 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l
ALOGE("Unable to reopen whitelisted descriptors.");
dvmAbort();
}
+
+ if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) {
+ ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));
+ dvmAbort();
+ }
#endif /* HAVE_ANDROID_OS */
if (mountMode != MOUNT_EXTERNAL_NONE) {
@@ -844,6 +866,13 @@ static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer, bool l
/* the parent process */
free(seInfo);
free(niceName);
+
+ // 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));
+ dvmAbort();
+ }
+
}
return pid;