From 40cd690901954548b0ed77dbd241f5892428ee9a Mon Sep 17 00:00:00 2001
From: "rsesek@chromium.org"
 <rsesek@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>
Date: Tue, 6 May 2014 19:52:55 +0000
Subject: [PATCH] FD leaks and handle errors better.

Patch from Matthew Dempsky <mdempsky@chromium.org>.
Original review: https://breakpad.appspot.com/5654002/

Review URL: https://breakpad.appspot.com/1674002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1326 4c0a9323-5329-0410-9bdc-e9ce6186880e
---
 .../crash_generation/crash_generation_client.cc    |  4 +++-
 src/client/linux/handler/exception_handler.cc      | 14 ++++++++++----
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/client/linux/crash_generation/crash_generation_client.cc b/src/client/linux/crash_generation/crash_generation_client.cc
index aed13e14..2522c955 100644
--- a/src/client/linux/crash_generation/crash_generation_client.cc
+++ b/src/client/linux/crash_generation/crash_generation_client.cc
@@ -74,8 +74,10 @@ class CrashGenerationClientImpl : public CrashGenerationClient {
 
     ssize_t ret = HANDLE_EINTR(sys_sendmsg(server_fd_, &msg, 0));
     sys_close(fds[1]);
-    if (ret < 0)
+    if (ret < 0) {
+      sys_close(fds[0]);
       return false;
+    }
 
     // Wait for an ACK from the server.
     char b;
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
index 39c808ff..8a0cddad 100644
--- a/src/client/linux/handler/exception_handler.cc
+++ b/src/client/linux/handler/exception_handler.cc
@@ -474,19 +474,25 @@ bool ExceptionHandler::GenerateDump(CrashContext *context) {
     logger::write(no_pipe_msg, sizeof(no_pipe_msg) - 1);
     logger::write(strerror(errno), strlen(strerror(errno)));
     logger::write("\n", 1);
+
+    // Ensure fdes[0] and fdes[1] are invalid file descriptors.
+    fdes[0] = fdes[1] = -1;
   }
 
   const pid_t child = sys_clone(
       ThreadEntry, stack, CLONE_FILES | CLONE_FS | CLONE_UNTRACED,
       &thread_arg, NULL, NULL, NULL);
+  if (child == -1) {
+    sys_close(fdes[0]);
+    sys_close(fdes[1]);
+    return false;
+  }
 
-  int r, status;
   // Allow the child to ptrace us
   sys_prctl(PR_SET_PTRACER, child, 0, 0, 0);
   SendContinueSignalToChild();
-  do {
-    r = sys_waitpid(child, &status, __WALL);
-  } while (r == -1 && errno == EINTR);
+  int status;
+  const int r = HANDLE_EINTR(sys_waitpid(child, &status, __WALL));
 
   sys_close(fdes[0]);
   sys_close(fdes[1]);