| Index: components/nacl/loader/nacl_helper_linux.cc
|
| diff --git a/components/nacl/loader/nacl_helper_linux.cc b/components/nacl/loader/nacl_helper_linux.cc
|
| index 68d0ff66ce6d93fa48574360e22a17e2fc85bf1c..018fd87f1de07bfaf8fbf366e95f97a791df9c79 100644
|
| --- a/components/nacl/loader/nacl_helper_linux.cc
|
| +++ b/components/nacl/loader/nacl_helper_linux.cc
|
| @@ -21,8 +21,10 @@
|
|
|
| #include "base/at_exit.h"
|
| #include "base/command_line.h"
|
| +#include "base/files/scoped_file.h"
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/memory/scoped_vector.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/posix/eintr_wrapper.h"
|
| #include "base/posix/global_descriptors.h"
|
| @@ -61,7 +63,7 @@ void ReplaceFDWithDummy(int file_descriptor) {
|
| // The child must mimic the behavior of zygote_main_linux.cc on the child
|
| // side of the fork. See zygote_main_linux.cc:HandleForkRequest from
|
| // if (!child) {
|
| -void BecomeNaClLoader(const std::vector<int>& child_fds,
|
| +void BecomeNaClLoader(base::ScopedFD browser_fd,
|
| const NaClLoaderSystemInfo& system_info,
|
| bool uses_nonsfi_mode,
|
| nacl::NaClSandbox* nacl_sandbox) {
|
| @@ -90,9 +92,8 @@ void BecomeNaClLoader(const std::vector<int>& child_fds,
|
| nacl_sandbox->SealLayerOneSandbox();
|
| nacl_sandbox->CheckSandboxingStateWithPolicy();
|
|
|
| - base::GlobalDescriptors::GetInstance()->Set(
|
| - kPrimaryIPCChannel,
|
| - child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]);
|
| + base::GlobalDescriptors::GetInstance()->Set(kPrimaryIPCChannel,
|
| + browser_fd.release());
|
|
|
| base::MessageLoopForIO main_message_loop;
|
| NaClListener listener;
|
| @@ -104,22 +105,21 @@ void BecomeNaClLoader(const std::vector<int>& child_fds,
|
| }
|
|
|
| // Start the NaCl loader in a child created by the NaCl loader Zygote.
|
| -void ChildNaClLoaderInit(const std::vector<int>& child_fds,
|
| +void ChildNaClLoaderInit(ScopedVector<base::ScopedFD> child_fds,
|
| const NaClLoaderSystemInfo& system_info,
|
| bool uses_nonsfi_mode,
|
| nacl::NaClSandbox* nacl_sandbox,
|
| const std::string& channel_id) {
|
| - const int parent_fd = child_fds[content::ZygoteForkDelegate::kParentFDIndex];
|
| - const int dummy_fd = child_fds[content::ZygoteForkDelegate::kDummyFDIndex];
|
| -
|
| bool validack = false;
|
| base::ProcessId real_pid;
|
| // Wait until the parent process has discovered our PID. We
|
| // should not fork any child processes (which the seccomp
|
| // sandbox does) until then, because that can interfere with the
|
| // parent's discovery of our PID.
|
| - const ssize_t nread =
|
| - HANDLE_EINTR(read(parent_fd, &real_pid, sizeof(real_pid)));
|
| + const ssize_t nread = HANDLE_EINTR(
|
| + read(child_fds[content::ZygoteForkDelegate::kParentFDIndex]->get(),
|
| + &real_pid,
|
| + sizeof(real_pid)));
|
| if (static_cast<size_t>(nread) == sizeof(real_pid)) {
|
| // Make sure the parent didn't accidentally send us our real PID.
|
| // We don't want it to be discoverable anywhere in our address space
|
| @@ -135,12 +135,13 @@ void ChildNaClLoaderInit(const std::vector<int>& child_fds,
|
| LOG(ERROR) << "read returned " << nread;
|
| }
|
|
|
| - if (IGNORE_EINTR(close(dummy_fd)) != 0)
|
| - LOG(ERROR) << "close(dummy_fd) failed";
|
| - if (IGNORE_EINTR(close(parent_fd)) != 0)
|
| - LOG(ERROR) << "close(parent_fd) failed";
|
| + base::ScopedFD browser_fd(
|
| + child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]->Pass());
|
| + child_fds.clear();
|
| +
|
| if (validack) {
|
| - BecomeNaClLoader(child_fds, system_info, uses_nonsfi_mode, nacl_sandbox);
|
| + BecomeNaClLoader(
|
| + browser_fd.Pass(), system_info, uses_nonsfi_mode, nacl_sandbox);
|
| } else {
|
| LOG(ERROR) << "Failed to synch with zygote";
|
| }
|
| @@ -150,7 +151,7 @@ void ChildNaClLoaderInit(const std::vector<int>& child_fds,
|
| // Handle a fork request from the Zygote.
|
| // Some of this code was lifted from
|
| // content/browser/zygote_main_linux.cc:ForkWithRealPid()
|
| -bool HandleForkRequest(const std::vector<int>& child_fds,
|
| +bool HandleForkRequest(ScopedVector<base::ScopedFD> child_fds,
|
| const NaClLoaderSystemInfo& system_info,
|
| nacl::NaClSandbox* nacl_sandbox,
|
| PickleIterator* input_iter,
|
| @@ -180,18 +181,18 @@ bool HandleForkRequest(const std::vector<int>& child_fds,
|
| }
|
|
|
| if (child_pid == 0) {
|
| - ChildNaClLoaderInit(
|
| - child_fds, system_info, uses_nonsfi_mode, nacl_sandbox, channel_id);
|
| + ChildNaClLoaderInit(child_fds.Pass(),
|
| + system_info,
|
| + uses_nonsfi_mode,
|
| + nacl_sandbox,
|
| + channel_id);
|
| NOTREACHED();
|
| }
|
|
|
| // I am the parent.
|
| // First, close the dummy_fd so the sandbox won't find me when
|
| // looking for the child's pid in /proc. Also close other fds.
|
| - for (size_t i = 0; i < child_fds.size(); i++) {
|
| - if (IGNORE_EINTR(close(child_fds[i])) != 0)
|
| - LOG(ERROR) << "close(child_fds[i]) failed";
|
| - }
|
| + child_fds.clear();
|
| VLOG(1) << "nacl_helper: child_pid is " << child_pid;
|
|
|
| // Now send child_pid (eventually -1 if fork failed) to the Chrome Zygote.
|
| @@ -234,7 +235,7 @@ bool HandleGetTerminationStatusRequest(PickleIterator* input_iter,
|
| // Reply to the command on |reply_fds|.
|
| bool HonorRequestAndReply(int reply_fd,
|
| int command_type,
|
| - const std::vector<int>& attached_fds,
|
| + ScopedVector<base::ScopedFD> attached_fds,
|
| const NaClLoaderSystemInfo& system_info,
|
| nacl::NaClSandbox* nacl_sandbox,
|
| PickleIterator* input_iter) {
|
| @@ -243,8 +244,11 @@ bool HonorRequestAndReply(int reply_fd,
|
| // Commands must write anything to send back to |write_pickle|.
|
| switch (command_type) {
|
| case nacl::kNaClForkRequest:
|
| - have_to_reply = HandleForkRequest(
|
| - attached_fds, system_info, nacl_sandbox, input_iter, &write_pickle);
|
| + have_to_reply = HandleForkRequest(attached_fds.Pass(),
|
| + system_info,
|
| + nacl_sandbox,
|
| + input_iter,
|
| + &write_pickle);
|
| break;
|
| case nacl::kNaClGetTerminationStatusRequest:
|
| have_to_reply =
|
| @@ -270,7 +274,7 @@ bool HonorRequestAndReply(int reply_fd,
|
| bool HandleZygoteRequest(int zygote_ipc_fd,
|
| const NaClLoaderSystemInfo& system_info,
|
| nacl::NaClSandbox* nacl_sandbox) {
|
| - std::vector<int> fds;
|
| + ScopedVector<base::ScopedFD> fds;
|
| char buf[kNaClMaxIPCMessageLength];
|
| const ssize_t msglen = UnixDomainSocket::RecvMsg(zygote_ipc_fd,
|
| &buf, sizeof(buf), &fds);
|
| @@ -297,8 +301,12 @@ bool HandleZygoteRequest(int zygote_ipc_fd,
|
| LOG(ERROR) << "Unable to read command from Zygote";
|
| return false;
|
| }
|
| - return HonorRequestAndReply(
|
| - zygote_ipc_fd, command_type, fds, system_info, nacl_sandbox, &read_iter);
|
| + return HonorRequestAndReply(zygote_ipc_fd,
|
| + command_type,
|
| + fds.Pass(),
|
| + system_info,
|
| + nacl_sandbox,
|
| + &read_iter);
|
| }
|
|
|
| static const char kNaClHelperReservedAtZero[] = "reserved_at_zero";
|
|
|