Index: content/browser/zygote_main_linux.cc |
diff --git a/content/browser/zygote_main_linux.cc b/content/browser/zygote_main_linux.cc |
index ef9dd0be039ba4e78c3f8936ccdde8b1e0b32aa7..c530f4adce00e7e3e0880a0b5dfd968d29282ef0 100644 |
--- a/content/browser/zygote_main_linux.cc |
+++ b/content/browser/zygote_main_linux.cc |
@@ -47,6 +47,7 @@ |
#include "content/common/sandbox_methods_linux.h" |
#include "content/common/set_process_title.h" |
#include "content/common/unix_domain_socket_posix.h" |
+#include "content/common/zygote_fork_delegate.h" |
#include "media/base/media.h" |
#include "seccompsandbox/sandbox.h" |
#include "skia/ext/SkFontHost_fontconfig_control.h" |
@@ -95,8 +96,9 @@ static void SELinuxTransitionToTypeOrDie(const char* type) { |
// runs it. |
class Zygote { |
public: |
- explicit Zygote(int sandbox_flags) |
- : sandbox_flags_(sandbox_flags) { |
+ explicit Zygote(int sandbox_flags, ZygoteForkDelegate* helper) |
+ : sandbox_flags_(sandbox_flags), |
+ helper_(helper) { |
} |
bool ProcessRequests() { |
@@ -158,11 +160,14 @@ class Zygote { |
void* iter = NULL; |
int kind; |
+ std::string process_type; |
if (pickle.ReadInt(&iter, &kind)) { |
switch (kind) { |
case ZygoteHost::kCmdFork: |
// This function call can return multiple times, once per fork(). |
- return HandleForkRequest(fd, pickle, iter, fds); |
+ pickle.ReadString(&iter, &process_type); |
+ return HandleForkRequest(fd, pickle, iter, fds, process_type); |
+ |
case ZygoteHost::kCmdReap: |
if (!fds.empty()) |
break; |
@@ -245,9 +250,16 @@ class Zygote { |
// sandbox, it returns the real PID of the child process as it |
// appears outside the sandbox, rather than returning the PID inside |
// the sandbox. |
- int ForkWithRealPid() { |
- if (!g_suid_sandbox_active) |
- return fork(); |
+ int ForkWithRealPid(const std::string process_type, std::vector<int>& fds) { |
+ if (!g_suid_sandbox_active) { |
+ VLOG(1) << "suid sandbox NOT active"; |
+ VLOG(1) << "fds.size() is " << fds.size(); |
+ if (helper_->CanHelp(process_type)) { |
+ return helper_->Fork(fds); |
+ } else { |
+ return fork(); |
+ } |
+ } |
int dummy_fd; |
ino_t dummy_inode; |
@@ -268,7 +280,13 @@ class Zygote { |
goto error; |
} |
- pid = fork(); |
+ if (helper_->CanHelp(process_type)) { |
+ fds.push_back(dummy_fd); |
+ fds.push_back(pipe_fds[0]); |
+ pid = helper_->Fork(fds); |
+ } else { |
+ pid = fork(); |
+ } |
if (pid < 0) { |
goto error; |
} else if (pid == 0) { |
@@ -340,8 +358,9 @@ class Zygote { |
// Handle a 'fork' request from the browser: this means that the browser |
// wishes to start a new renderer. |
- bool HandleForkRequest(int fd, const Pickle& pickle, void* iter, |
- std::vector<int>& fds) { |
+ bool HandleForkRequest(int fd, const Pickle& pickle, |
+ void* iter, std::vector<int>& fds, |
+ const std::string process_type) { |
std::vector<std::string> args; |
int argc, numfds; |
base::GlobalDescriptors::Mapping mapping; |
@@ -372,7 +391,7 @@ class Zygote { |
mapping.push_back(std::make_pair( |
static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor)); |
- child = ForkWithRealPid(); |
+ child = ForkWithRealPid(process_type, fds); |
if (!child) { |
#if defined(SECCOMP_SANDBOX) |
@@ -445,6 +464,7 @@ class Zygote { |
ProcessMap real_pids_to_sandbox_pids; |
const int sandbox_flags_; |
+ ZygoteForkDelegate* helper_; |
}; |
// With SELinux we can carve out a precise sandbox, so we don't have to play |
@@ -709,7 +729,8 @@ static bool EnterSandbox() { |
#endif // CHROMIUM_SELINUX |
-bool ZygoteMain(const MainFunctionParams& params) { |
+bool ZygoteMain(const MainFunctionParams& params, |
+ ZygoteForkDelegate* forkdelegate) { |
#if !defined(CHROMIUM_SELINUX) |
g_am_zygote_or_renderer = true; |
#endif |
@@ -728,6 +749,11 @@ bool ZygoteMain(const MainFunctionParams& params) { |
} |
#endif // SECCOMP_SANDBOX |
+ // initialize the fork helper |
+ VLOG(1) << "initializing fork delegate"; |
+ forkdelegate->Init(getenv("SBX_D") != NULL, // g_suid_sandbox_active, |
+ kBrowserDescriptor, kMagicSandboxIPCDescriptor); |
+ |
// Turn on the SELinux or SUID sandbox |
if (!EnterSandbox()) { |
LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " |
@@ -764,7 +790,7 @@ bool ZygoteMain(const MainFunctionParams& params) { |
} |
#endif // SECCOMP_SANDBOX |
- Zygote zygote(sandbox_flags); |
+ Zygote zygote(sandbox_flags, forkdelegate); |
// This function call can return multiple times, once per fork(). |
return zygote.ProcessRequests(); |
} |