summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2015-08-31 15:40:01 -0700
committerChristopher Ferris <cferris@google.com>2015-08-31 16:36:14 -0700
commita8a795428acf5cbe1cd348aa766243203ca78b80 (patch)
treea0e2e30c8a7c8ade0a5e3215ae7eabac1ef11378 /core
parent7878eee8a9c20752e038f563b98b6b42c372cd0f (diff)
downloadframeworks_base-a8a795428acf5cbe1cd348aa766243203ca78b80.zip
frameworks_base-a8a795428acf5cbe1cd348aa766243203ca78b80.tar.gz
frameworks_base-a8a795428acf5cbe1cd348aa766243203ca78b80.tar.bz2
Save/restore errno in SIGCHLD handler.
The SIGCHLD handler can set the errno, which can change the errno found on the thread on which the signal handler is invoked. Most of the time this is harmless, but it's possible that if the main thread was making a system call, and allows certain failures based on errno, that logic can fail. The fix is to save/restore errno in the handler. Bug: 23572286 Bug: 23689391 Change-Id: I4542fd60cc1398ce0a8902d8df98a3d089fb6efe
Diffstat (limited to 'core')
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 4c920dc..b431a3f 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -83,6 +83,14 @@ static void SigChldHandler(int /*signal_number*/) {
pid_t pid;
int status;
+ // It's necessary to save and restore the errno during this function.
+ // Since errno is stored per thread, changing it here modifies the errno
+ // on the thread on which this signal handler executes. If a signal occurs
+ // between a call and an errno check, it's possible to get the errno set
+ // here.
+ // See b/23572286 for extra information.
+ int saved_errno = errno;
+
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
// Log process-death status that we care about. In general it is
// not safe to call LOG(...) from a signal handler because of
@@ -118,6 +126,8 @@ static void SigChldHandler(int /*signal_number*/) {
if (pid < 0 && errno != ECHILD) {
ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
}
+
+ errno = saved_errno;
}
// Configures the SIGCHLD handler for the zygote process. This is configured