Index: content/zygote/zygote_main_linux.cc |
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc |
index 361511e37374cee7b9546059d05fb8f2405ad411..c5860e4052c9fff015fc8edac9f8013c711fcf4c 100644 |
--- a/content/zygote/zygote_main_linux.cc |
+++ b/content/zygote/zygote_main_linux.cc |
@@ -13,6 +13,8 @@ |
#include <sys/types.h> |
#include <unistd.h> |
+#include <vector> |
+ |
#include "base/basictypes.h" |
#include "base/bind.h" |
#include "base/command_line.h" |
@@ -101,6 +103,13 @@ void InstallSandboxCrashTestHandler() { |
PCHECK(0 == sigaction(SIGUSR2, &act, NULL)); |
} |
+ |
+void CloseFds(const std::vector<int>& fds) { |
+ for (const auto& it : fds) { |
+ PCHECK(0 == IGNORE_EINTR(close(it))); |
+ } |
+} |
+ |
} // namespace |
// See http://code.google.com/p/chromium/wiki/LinuxZygote |
@@ -494,13 +503,17 @@ static void CreateSanitizerCoverageSocketPair(int fds[2]) { |
PCHECK(0 == shutdown(fds[1], SHUT_RD)); |
} |
-static pid_t ForkSanitizerCoverageHelper(int child_fd, int parent_fd, |
- base::ScopedFD file_fd) { |
+static pid_t ForkSanitizerCoverageHelper( |
+ int child_fd, |
+ int parent_fd, |
+ base::ScopedFD file_fd, |
+ const std::vector<int>& extra_fds_to_close) { |
pid_t pid = fork(); |
PCHECK(pid >= 0); |
if (pid == 0) { |
// In the child. |
PCHECK(0 == IGNORE_EINTR(close(parent_fd))); |
+ CloseFds(extra_fds_to_close); |
SanitizerCoverageHelper(child_fd, file_fd.get()); |
_exit(0); |
} else { |
@@ -510,10 +523,6 @@ static pid_t ForkSanitizerCoverageHelper(int child_fd, int parent_fd, |
} |
} |
-void CloseFdPair(const int fds[2]) { |
- PCHECK(0 == IGNORE_EINTR(close(fds[0]))); |
- PCHECK(0 == IGNORE_EINTR(close(fds[1]))); |
-} |
#endif // defined(ADDRESS_SANITIZER) |
// If |is_suid_sandbox_child|, then make sure that the setuid sandbox is |
@@ -544,7 +553,7 @@ bool ZygoteMain(const MainFunctionParams& params, |
g_am_zygote_or_renderer = true; |
sandbox::InitLibcUrandomOverrides(); |
- base::Closure *post_fork_parent_callback = NULL; |
+ std::vector<int> fds_to_close_post_fork; |
LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); |
@@ -562,9 +571,8 @@ bool ZygoteMain(const MainFunctionParams& params, |
// Zygote termination will block until the helper process exits, which will |
// not happen until the write end of the socket is closed everywhere. Make |
// sure the init process does not hold on to it. |
- base::Closure close_sancov_socket_fds = |
- base::Bind(&CloseFdPair, sancov_socket_fds); |
- post_fork_parent_callback = &close_sancov_socket_fds; |
+ fds_to_close_post_fork.push_back(sancov_socket_fds[0]); |
+ fds_to_close_post_fork.push_back(sancov_socket_fds[1]); |
#endif |
// This will pre-initialize the various sandboxes that need it. |
@@ -590,16 +598,28 @@ bool ZygoteMain(const MainFunctionParams& params, |
(*i)->Init(GetSandboxFD(), must_enable_setuid_sandbox); |
} |
+ const std::vector<int> sandbox_fds_to_close_post_fork = |
+ linux_sandbox->GetFileDescriptorsToClose(); |
+ |
+ fds_to_close_post_fork.insert(fds_to_close_post_fork.end(), |
+ sandbox_fds_to_close_post_fork.begin(), |
+ sandbox_fds_to_close_post_fork.end()); |
+ base::Closure post_fork_parent_callback = |
+ base::Bind(&CloseFds, fds_to_close_post_fork); |
+ |
// Turn on the first layer of the sandbox if the configuration warrants it. |
EnterLayerOneSandbox(linux_sandbox, must_enable_setuid_sandbox, |
- post_fork_parent_callback); |
+ &post_fork_parent_callback); |
+ // Extra children and file descriptors created that the Zygote must have |
+ // knowledge of. |
std::vector<pid_t> extra_children; |
std::vector<int> extra_fds; |
#if defined(ADDRESS_SANITIZER) |
pid_t sancov_helper_pid = ForkSanitizerCoverageHelper( |
- sancov_socket_fds[0], sancov_socket_fds[1], sancov_file_fd.Pass()); |
+ sancov_socket_fds[0], sancov_socket_fds[1], sancov_file_fd.Pass(), |
+ sandbox_fds_to_close_post_fork); |
// It's important that the zygote reaps the helper before dying. Otherwise, |
// the destruction of the PID namespace could kill the helper before it |
// completes its I/O tasks. |sancov_helper_pid| will exit once the last |