Chromium Code Reviews| 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 a7c6615e51b11973b9c98d6d1f762de23d48fa31..0fbc05096f440ee022e0af6ae510702cbfb25e76 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" |
| @@ -128,7 +130,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) { |
| VLOG(1) << "NaCl loader: setting up IPC descriptor"; |
| @@ -150,9 +152,8 @@ void BecomeNaClLoader(const std::vector<int>& child_fds, |
| } |
| InitializeLayerTwoSandbox(uses_nonsfi_mode); |
| - 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; |
| @@ -164,21 +165,20 @@ 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, |
| 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 |
| @@ -194,12 +194,12 @@ void ChildNaClLoaderInit(const std::vector<int>& child_fds, |
| LOG(ERROR) << "read returned " << nread; |
| } |
|
jln (very slow on Chromium)
2014/04/28 23:48:55
We can't rely on the ScopedVector to release child
mdempsky
2014/04/29 00:10:33
As we discussed and you pointed out below, child_f
|
| - 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(); |
|
jln (very slow on Chromium)
2014/04/28 23:57:19
I had missed this one, so there is no leak.
|
| + |
| if (validack) { |
| - BecomeNaClLoader(child_fds, system_info, uses_nonsfi_mode); |
| + BecomeNaClLoader(browser_fd.Pass(), system_info, uses_nonsfi_mode); |
| } else { |
| LOG(ERROR) << "Failed to synch with zygote"; |
| } |
| @@ -209,7 +209,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, |
| PickleIterator* input_iter, |
| Pickle* output_pickle) { |
| @@ -238,17 +238,15 @@ bool HandleForkRequest(const std::vector<int>& child_fds, |
| } |
| if (child_pid == 0) { |
| - ChildNaClLoaderInit(child_fds, system_info, uses_nonsfi_mode, channel_id); |
| + ChildNaClLoaderInit( |
| + child_fds.Pass(), system_info, uses_nonsfi_mode, 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. |
| @@ -291,7 +289,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, |
| PickleIterator* input_iter) { |
| Pickle write_pickle; |
| @@ -299,8 +297,8 @@ 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, |
| - input_iter, &write_pickle); |
| + have_to_reply = HandleForkRequest( |
| + attached_fds.Pass(), system_info, input_iter, &write_pickle); |
| break; |
| case nacl::kNaClGetTerminationStatusRequest: |
| have_to_reply = |
| @@ -325,7 +323,7 @@ bool HonorRequestAndReply(int reply_fd, |
| // Die on EOF from |zygote_ipc_fd|. |
| bool HandleZygoteRequest(int zygote_ipc_fd, |
| const NaClLoaderSystemInfo& system_info) { |
| - std::vector<int> fds; |
| + ScopedVector<base::ScopedFD> fds; |
| char buf[kNaClMaxIPCMessageLength]; |
| const ssize_t msglen = UnixDomainSocket::RecvMsg(zygote_ipc_fd, |
| &buf, sizeof(buf), &fds); |
| @@ -352,8 +350,8 @@ 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, |
| - &read_iter); |
| + return HonorRequestAndReply( |
| + zygote_ipc_fd, command_type, fds.Pass(), system_info, &read_iter); |
| } |
| static const char kNaClHelperReservedAtZero[] = "reserved_at_zero"; |