Revert 90805 - I am submitting this with LGTMs from agl@ and evanm@. I'm marking this as TBR=jam@ because he is on vacation. He previously LGTMed the reverted CL (link below) and there are not substantive changes since then.

Modify the Chrome Linux zygote to support a nacl_helper executable,
facilitating a special address-space layout as required by NaCl on ARM
and ATOM CPUs. In passing, simplify some shared elements of launching
NaCl modules in Chrome.

This is an update to a previously reverted CL. Please see
http://codereview.chromium.org/6995121 for the earlier reviews.

Patching nacl_helper CL into fresh branch.

BUG=nativeclient:480
TEST=nativeclient in-browser tests
[email protected]

[email protected]
Review URL: http://codereview.chromium.org/7230057

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90813 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/zygote_main_linux.cc b/content/browser/zygote_main_linux.cc
index 477ca90e..99a7735 100644
--- a/content/browser/zygote_main_linux.cc
+++ b/content/browser/zygote_main_linux.cc
@@ -37,11 +37,9 @@
 #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_linux.h"
 #include "seccompsandbox/sandbox.h"
 #include "skia/ext/SkFontHost_fontconfig_control.h"
 #include "unicode/timezone.h"
-#include "ipc/ipc_switches.h"
 
 #if defined(OS_LINUX)
 #include <sys/epoll.h>
@@ -99,9 +97,8 @@
 // runs it.
 class Zygote {
  public:
-  explicit Zygote(int sandbox_flags, ZygoteForkDelegate& helper)
-    : sandbox_flags_(sandbox_flags),
-      helper_(helper) {
+  explicit Zygote(int sandbox_flags)
+      : sandbox_flags_(sandbox_flags) {
   }
 
   bool ProcessRequests() {
@@ -168,7 +165,6 @@
         case ZygoteHost::kCmdFork:
           // This function call can return multiple times, once per fork().
           return HandleForkRequest(fd, pickle, iter, fds);
-
         case ZygoteHost::kCmdReap:
           if (!fds.empty())
             break;
@@ -251,12 +247,9 @@
   // 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(const std::string& process_type, std::vector<int>& fds,
-                      const std::string& channel_switch) {
-    const bool use_helper = helper_.CanHelp(process_type);
-    if (!(use_helper || g_suid_sandbox_active)) {
+  int ForkWithRealPid() {
+    if (!g_suid_sandbox_active)
       return fork();
-    }
 
     int dummy_fd;
     ino_t dummy_inode;
@@ -277,13 +270,7 @@
       goto error;
     }
 
-    if (use_helper) {
-      fds.push_back(dummy_fd);
-      fds.push_back(pipe_fds[0]);
-      pid = helper_.Fork(fds);
-    } else {
-      pid = fork();
-    }
+    pid = fork();
     if (pid < 0) {
       goto error;
     } else if (pid == 0) {
@@ -307,43 +294,33 @@
       dummy_fd = -1;
       close(pipe_fds[0]);
       pipe_fds[0] = -1;
-      base::ProcessId real_pid;
-      if (g_suid_sandbox_active) {
-        uint8_t reply_buf[512];
-        Pickle request;
-        request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE);
-        request.WriteUInt64(dummy_inode);
+      uint8_t reply_buf[512];
+      Pickle request;
+      request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE);
+      request.WriteUInt64(dummy_inode);
 
-        const ssize_t r = UnixDomainSocket::SendRecvMsg(
-            kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL,
-            request);
-        if (r == -1) {
-          LOG(ERROR) << "Failed to get child process's real PID";
-          goto error;
-        }
-
-        Pickle reply(reinterpret_cast<char*>(reply_buf), r);
-        void* iter = NULL;
-        if (!reply.ReadInt(&iter, &real_pid))
-          goto error;
-        if (real_pid <= 0) {
-          // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already?
-          LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed";
-          goto error;
-        }
-        real_pids_to_sandbox_pids[real_pid] = pid;
+      const ssize_t r = UnixDomainSocket::SendRecvMsg(
+          kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL,
+          request);
+      if (r == -1) {
+        LOG(ERROR) << "Failed to get child process's real PID";
+        goto error;
       }
-      if (use_helper) {
-        real_pid = pid;
-        if (!helper_.AckChild(pipe_fds[1], channel_switch)) {
-          LOG(ERROR) << "Failed to synchronise with NaCl child process";
-          goto error;
-        }
-      } else {
-        if (HANDLE_EINTR(write(pipe_fds[1], "x", 1)) != 1) {
-          LOG(ERROR) << "Failed to synchronise with child process";
-          goto error;
-        }
+
+      base::ProcessId real_pid;
+      Pickle reply(reinterpret_cast<char*>(reply_buf), r);
+      void* iter2 = NULL;
+      if (!reply.ReadInt(&iter2, &real_pid))
+        goto error;
+      if (real_pid <= 0) {
+        // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already?
+        LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed";
+        goto error;
+      }
+      real_pids_to_sandbox_pids[real_pid] = pid;
+      if (HANDLE_EINTR(write(pipe_fds[1], "x", 1)) != 1) {
+        LOG(ERROR) << "Failed to synchronise with child process";
+        goto error;
       }
       close(pipe_fds[1]);
       return real_pid;
@@ -365,19 +342,12 @@
 
   // 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) {
     std::vector<std::string> args;
     int argc, numfds;
     base::GlobalDescriptors::Mapping mapping;
     base::ProcessId child;
-    std::string process_type;
-    std::string channel_id;
-    const std::string channel_id_prefix = std::string("--")
-        + switches::kProcessChannelID + std::string("=");
-
-    if (!pickle.ReadString(&iter, &process_type))
-      goto error;
 
     if (!pickle.ReadInt(&iter, &argc))
       goto error;
@@ -387,8 +357,6 @@
       if (!pickle.ReadString(&iter, &arg))
         goto error;
       args.push_back(arg);
-      if (arg.compare(0, channel_id_prefix.length(), channel_id_prefix) == 0)
-        channel_id = arg;
     }
 
     if (!pickle.ReadInt(&iter, &numfds))
@@ -406,7 +374,7 @@
     mapping.push_back(std::make_pair(
         static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor));
 
-    child = ForkWithRealPid(process_type, fds, channel_id);
+    child = ForkWithRealPid();
 
     if (!child) {
 #if defined(SECCOMP_SANDBOX)
@@ -479,7 +447,6 @@
   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
@@ -738,8 +705,7 @@
 
 #endif  // CHROMIUM_SELINUX
 
-bool ZygoteMain(const MainFunctionParams& params,
-                const ZygoteForkDelegate& forkdelegate) {
+bool ZygoteMain(const MainFunctionParams& params) {
 #if !defined(CHROMIUM_SELINUX)
   g_am_zygote_or_renderer = true;
 #endif
@@ -758,10 +724,6 @@
   }
 #endif  // SECCOMP_SANDBOX
 
-  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: "
@@ -798,7 +760,7 @@
   }
 #endif  // SECCOMP_SANDBOX
 
-  Zygote zygote(sandbox_flags, forkdelegate);
+  Zygote zygote(sandbox_flags);
   // This function call can return multiple times, once per fork().
   return zygote.ProcessRequests();
 }