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"; |