| Index: content/zygote/zygote_main_linux.cc | 
| diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc | 
| index 7a79ab3f2c76f4940be1aff5133046fbace668c0..93ab269b3a6fff8a60a40a9d7d0a7b4e2a66fccd 100644 | 
| --- a/content/zygote/zygote_main_linux.cc | 
| +++ b/content/zygote/zygote_main_linux.cc | 
| @@ -15,6 +15,8 @@ | 
| #include <unistd.h> | 
|  | 
| #include "base/basictypes.h" | 
| +#include "base/bind.h" | 
| +#include "base/callback.h" | 
| #include "base/command_line.h" | 
| #include "base/linux_util.h" | 
| #include "base/native_library.h" | 
| @@ -308,80 +310,8 @@ static void PreSandboxInit() { | 
| new FontConfigIPC(GetSandboxFD()))->unref(); | 
| } | 
|  | 
| -// Do nothing here | 
| -static void SIGCHLDHandler(int signal) { | 
| -} | 
| - | 
| -// The current process will become a process reaper like init. | 
| -// We fork a child that will continue normally, when it dies, we can safely | 
| -// exit. | 
| -// We need to be careful we close the magic kZygoteIdFd properly in the parent | 
| -// before this function returns. | 
| -static bool CreateInitProcessReaper() { | 
| -  int sync_fds[2]; | 
| -  // We want to use send, so we can't use a pipe | 
| -  if (socketpair(AF_UNIX, SOCK_STREAM, 0, sync_fds)) { | 
| -    LOG(ERROR) << "Failed to create socketpair"; | 
| -    return false; | 
| -  } | 
| - | 
| -  // We use normal fork, not the ForkDelegate in this case since we are not a | 
| -  // true Zygote yet. | 
| -  pid_t child_pid = fork(); | 
| -  if (child_pid == -1) { | 
| -    (void) HANDLE_EINTR(close(sync_fds[0])); | 
| -    (void) HANDLE_EINTR(close(sync_fds[1])); | 
| -    return false; | 
| -  } | 
| -  if (child_pid) { | 
| -    // We are the parent, assuming the role of an init process. | 
| -    // The disposition for SIGCHLD cannot be SIG_IGN or wait() will only return | 
| -    // once all of our childs are dead. Since we're init we need to reap childs | 
| -    // as they come. | 
| -    struct sigaction action; | 
| -    memset(&action, 0, sizeof(action)); | 
| -    action.sa_handler = &SIGCHLDHandler; | 
| -    CHECK(sigaction(SIGCHLD, &action, NULL) == 0); | 
| - | 
| -    (void) HANDLE_EINTR(close(sync_fds[0])); | 
| -    shutdown(sync_fds[1], SHUT_RD); | 
| -    // This "magic" socket must only appear in one process. | 
| -    (void) HANDLE_EINTR(close(kZygoteIdFd)); | 
| -    // Tell the child to continue | 
| -    CHECK(HANDLE_EINTR(send(sync_fds[1], "C", 1, MSG_NOSIGNAL)) == 1); | 
| -    (void) HANDLE_EINTR(close(sync_fds[1])); | 
| - | 
| -    for (;;) { | 
| -      // Loop until we have reaped our one natural child | 
| -      siginfo_t reaped_child_info; | 
| -      int wait_ret = | 
| -        HANDLE_EINTR(waitid(P_ALL, 0, &reaped_child_info, WEXITED)); | 
| -      if (wait_ret) | 
| -        _exit(1); | 
| -      if (reaped_child_info.si_pid == child_pid) { | 
| -        int exit_code = 0; | 
| -        // We're done waiting | 
| -        if (reaped_child_info.si_code == CLD_EXITED) { | 
| -          exit_code = reaped_child_info.si_status; | 
| -        } | 
| -        // Exit with the same exit code as our parent. This is most likely | 
| -        // useless. _exit with 0 if we got signaled. | 
| -        _exit(exit_code); | 
| -      } | 
| -    } | 
| -  } else { | 
| -    // The child needs to wait for the parent to close kZygoteIdFd to avoid a | 
| -    // race condition | 
| -    (void) HANDLE_EINTR(close(sync_fds[1])); | 
| -    shutdown(sync_fds[0], SHUT_WR); | 
| -    char should_continue; | 
| -    int read_ret = HANDLE_EINTR(read(sync_fds[0], &should_continue, 1)); | 
| -    (void) HANDLE_EINTR(close(sync_fds[0])); | 
| -    if (read_ret == 1) | 
| -      return true; | 
| -    else | 
| -      return false; | 
| -  } | 
| +static void CloseFdAndHandleEintr(int fd) { | 
| +  (void) HANDLE_EINTR(close(fd)); | 
| } | 
|  | 
| // This will set the *using_suid_sandbox variable to true if the SUID sandbox | 
| @@ -421,7 +351,13 @@ static bool EnterSuidSandbox(LinuxSandbox* linux_sandbox, | 
| if (getpid() == 1) { | 
| // The setuid sandbox has created a new PID namespace and we need | 
| // to assume the role of init. | 
| -      if (!CreateInitProcessReaper()) { | 
| +      // This "magic" socket must only appear in one process, so make sure | 
| +      // it gets closed in the parent after fork(). | 
| +      base::Closure zygoteid_fd_closer = | 
| +          base::Bind(CloseFdAndHandleEintr, kZygoteIdFd); | 
| +      const bool init_created = | 
| +          setuid_sandbox->CreateInitProcessReaper(&zygoteid_fd_closer); | 
| +      if (!init_created) { | 
| LOG(ERROR) << "Error creating an init process to reap zombies"; | 
| return false; | 
| } | 
|  |