From a8a795428acf5cbe1cd348aa766243203ca78b80 Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Mon, 31 Aug 2015 15:40:01 -0700 Subject: [PATCH] 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 --- core/jni/com_android_internal_os_Zygote.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 4c920dc2c20a8..b431a3f487fad 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