Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1681)

Unified Diff: content/zygote/zygote_main_linux.cc

Issue 90243002: Extract CreateInitProcessReaper() from the Zygote. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sandbox/linux/sandbox_linux.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « no previous file | sandbox/linux/sandbox_linux.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698