Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: chrome/nacl/nacl_helper_linux.cc

Issue 24449002: NaCl: Clean up how FDs are passed to nacl_helper instances on Linux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup: move constants Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // A mini-zygote specifically for Native Client. 5 // A mini-zygote specifically for Native Client.
6 6
7 #include "components/nacl/common/nacl_helper_linux.h" 7 #include "components/nacl/common/nacl_helper_linux.h"
8 8
9 #include <errno.h> 9 #include <errno.h>
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 12 matching lines...) Expand all
23 #include "base/command_line.h" 23 #include "base/command_line.h"
24 #include "base/logging.h" 24 #include "base/logging.h"
25 #include "base/message_loop/message_loop.h" 25 #include "base/message_loop/message_loop.h"
26 #include "base/posix/eintr_wrapper.h" 26 #include "base/posix/eintr_wrapper.h"
27 #include "base/posix/global_descriptors.h" 27 #include "base/posix/global_descriptors.h"
28 #include "base/posix/unix_domain_socket_linux.h" 28 #include "base/posix/unix_domain_socket_linux.h"
29 #include "base/process/kill.h" 29 #include "base/process/kill.h"
30 #include "base/rand_util.h" 30 #include "base/rand_util.h"
31 #include "components/nacl/loader/nacl_listener.h" 31 #include "components/nacl/loader/nacl_listener.h"
32 #include "components/nacl/loader/nacl_sandbox_linux.h" 32 #include "components/nacl/loader/nacl_sandbox_linux.h"
33 #include "content/public/common/zygote_fork_delegate_linux.h"
33 #include "crypto/nss_util.h" 34 #include "crypto/nss_util.h"
34 #include "ipc/ipc_descriptors.h" 35 #include "ipc/ipc_descriptors.h"
35 #include "ipc/ipc_switches.h" 36 #include "ipc/ipc_switches.h"
36 #include "sandbox/linux/services/libc_urandom_override.h" 37 #include "sandbox/linux/services/libc_urandom_override.h"
37 38
38 namespace { 39 namespace {
39 40
40 struct NaClLoaderSystemInfo { 41 struct NaClLoaderSystemInfo {
41 size_t prereserved_sandbox_size; 42 size_t prereserved_sandbox_size;
42 long number_of_cores; 43 long number_of_cores;
43 }; 44 };
44 45
45 // The child must mimic the behavior of zygote_main_linux.cc on the child 46 // The child must mimic the behavior of zygote_main_linux.cc on the child
46 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from 47 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from
47 // if (!child) { 48 // if (!child) {
48 void BecomeNaClLoader(const std::vector<int>& child_fds, 49 void BecomeNaClLoader(const std::vector<int>& child_fds,
49 const NaClLoaderSystemInfo& system_info) { 50 const NaClLoaderSystemInfo& system_info) {
50 VLOG(1) << "NaCl loader: setting up IPC descriptor"; 51 VLOG(1) << "NaCl loader: setting up IPC descriptor";
51 // don't need zygote FD any more 52 // don't need zygote FD any more
52 if (HANDLE_EINTR(close(kNaClZygoteDescriptor)) != 0) 53 if (HANDLE_EINTR(close(kNaClZygoteDescriptor)) != 0)
53 LOG(ERROR) << "close(kNaClZygoteDescriptor) failed."; 54 LOG(ERROR) << "close(kNaClZygoteDescriptor) failed.";
54 bool sandbox_initialized = InitializeBpfSandbox(); 55 bool sandbox_initialized = InitializeBpfSandbox();
55 if (!sandbox_initialized) { 56 if (!sandbox_initialized) {
56 LOG(ERROR) << "Could not initialize NaCl's second " 57 LOG(ERROR) << "Could not initialize NaCl's second "
57 << "layer sandbox (seccomp-bpf)."; 58 << "layer sandbox (seccomp-bpf).";
58 } 59 }
59 base::GlobalDescriptors::GetInstance()->Set(kPrimaryIPCChannel, 60 base::GlobalDescriptors::GetInstance()->Set(
60 child_fds[kNaClBrowserFDIndex]); 61 kPrimaryIPCChannel,
62 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]);
61 63
62 base::MessageLoopForIO main_message_loop; 64 base::MessageLoopForIO main_message_loop;
63 NaClListener listener; 65 NaClListener listener;
64 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size); 66 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size);
65 listener.set_number_of_cores(system_info.number_of_cores); 67 listener.set_number_of_cores(system_info.number_of_cores);
66 listener.Listen(); 68 listener.Listen();
67 _exit(0); 69 _exit(0);
68 } 70 }
69 71
70 // Start the NaCl loader in a child created by the NaCl loader Zygote. 72 // Start the NaCl loader in a child created by the NaCl loader Zygote.
71 void ChildNaClLoaderInit(const std::vector<int>& child_fds, 73 void ChildNaClLoaderInit(const std::vector<int>& child_fds,
72 const NaClLoaderSystemInfo& system_info) { 74 const NaClLoaderSystemInfo& system_info) {
75 int parent_fd = child_fds[content::ZygoteForkDelegate::kParentFDIndex];
jln (very slow on Chromium) 2013/10/07 18:12:06 Do you want to make these const?
Mark Seaborn 2013/10/08 18:31:06 I don't normally do that for local variables, but
76 int dummy_fd = child_fds[content::ZygoteForkDelegate::kDummyFDIndex];
73 bool validack = false; 77 bool validack = false;
74 const size_t kMaxReadSize = 1024; 78 const size_t kMaxReadSize = 1024;
75 char buffer[kMaxReadSize]; 79 char buffer[kMaxReadSize];
76 // Wait until the parent process has discovered our PID. We 80 // Wait until the parent process has discovered our PID. We
77 // should not fork any child processes (which the seccomp 81 // should not fork any child processes (which the seccomp
78 // sandbox does) until then, because that can interfere with the 82 // sandbox does) until then, because that can interfere with the
79 // parent's discovery of our PID. 83 // parent's discovery of our PID.
80 const int nread = HANDLE_EINTR(read(child_fds[kNaClParentFDIndex], buffer, 84 const int nread = HANDLE_EINTR(read(parent_fd, buffer, kMaxReadSize));
81 kMaxReadSize));
82 const std::string switch_prefix = std::string("--") + 85 const std::string switch_prefix = std::string("--") +
83 switches::kProcessChannelID + std::string("="); 86 switches::kProcessChannelID + std::string("=");
84 const size_t len = switch_prefix.length(); 87 const size_t len = switch_prefix.length();
85 88
86 if (nread < 0) { 89 if (nread < 0) {
87 perror("read"); 90 perror("read");
88 LOG(ERROR) << "read returned " << nread; 91 LOG(ERROR) << "read returned " << nread;
89 } else if (nread > static_cast<int>(len)) { 92 } else if (nread > static_cast<int>(len)) {
90 if (switch_prefix.compare(0, len, buffer, 0, len) == 0) { 93 if (switch_prefix.compare(0, len, buffer, 0, len) == 0) {
91 VLOG(1) << "NaCl loader is synchronised with Chrome zygote"; 94 VLOG(1) << "NaCl loader is synchronised with Chrome zygote";
92 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 95 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
93 switches::kProcessChannelID, 96 switches::kProcessChannelID,
94 std::string(&buffer[len], nread - len)); 97 std::string(&buffer[len], nread - len));
95 validack = true; 98 validack = true;
96 } 99 }
97 } 100 }
98 if (HANDLE_EINTR(close(child_fds[kNaClDummyFDIndex])) != 0) 101 if (HANDLE_EINTR(close(dummy_fd)) != 0)
99 LOG(ERROR) << "close(child_fds[kNaClDummyFDIndex]) failed"; 102 LOG(ERROR) << "close(dummy_fd) failed";
100 if (HANDLE_EINTR(close(child_fds[kNaClParentFDIndex])) != 0) 103 if (HANDLE_EINTR(close(parent_fd)) != 0)
101 LOG(ERROR) << "close(child_fds[kNaClParentFDIndex]) failed"; 104 LOG(ERROR) << "close(parent_fd) failed";
102 if (validack) { 105 if (validack) {
103 BecomeNaClLoader(child_fds, system_info); 106 BecomeNaClLoader(child_fds, system_info);
104 } else { 107 } else {
105 LOG(ERROR) << "Failed to synch with zygote"; 108 LOG(ERROR) << "Failed to synch with zygote";
106 } 109 }
107 _exit(1); 110 _exit(1);
108 } 111 }
109 112
110 // Handle a fork request from the Zygote. 113 // Handle a fork request from the Zygote.
111 // Some of this code was lifted from 114 // Some of this code was lifted from
112 // content/browser/zygote_main_linux.cc:ForkWithRealPid() 115 // content/browser/zygote_main_linux.cc:ForkWithRealPid()
113 bool HandleForkRequest(const std::vector<int>& child_fds, 116 bool HandleForkRequest(const std::vector<int>& child_fds,
114 const NaClLoaderSystemInfo& system_info, 117 const NaClLoaderSystemInfo& system_info,
115 Pickle* output_pickle) { 118 Pickle* output_pickle) {
116 if (kNaClParentFDIndex + 1 != child_fds.size()) { 119 if (content::ZygoteForkDelegate::kParentFDIndex + 1 != child_fds.size()) {
jln (very slow on Chromium) 2013/10/07 18:12:06 kNumPassedFds ? (see comment at the enum declarati
Mark Seaborn 2013/10/08 18:31:06 Done.
117 LOG(ERROR) << "nacl_helper: unexpected number of fds, got " 120 LOG(ERROR) << "nacl_helper: unexpected number of fds, got "
118 << child_fds.size(); 121 << child_fds.size();
119 return false; 122 return false;
120 } 123 }
121 124
122 VLOG(1) << "nacl_helper: forking"; 125 VLOG(1) << "nacl_helper: forking";
123 pid_t child_pid = fork(); 126 pid_t child_pid = fork();
124 if (child_pid < 0) { 127 if (child_pid < 0) {
125 PLOG(ERROR) << "*** fork() failed."; 128 PLOG(ERROR) << "*** fork() failed.";
126 } 129 }
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 // Now handle requests from the Zygote. 381 // Now handle requests from the Zygote.
379 while (true) { 382 while (true) {
380 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor, 383 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor,
381 system_info); 384 system_info);
382 // Do not turn this into a CHECK() without thinking about robustness 385 // Do not turn this into a CHECK() without thinking about robustness
383 // against malicious IPC requests. 386 // against malicious IPC requests.
384 DCHECK(request_handled); 387 DCHECK(request_handled);
385 } 388 }
386 NOTREACHED(); 389 NOTREACHED();
387 } 390 }
OLDNEW
« no previous file with comments | « no previous file | components/nacl/common/nacl_helper_linux.h » ('j') | components/nacl/zygote/nacl_fork_delegate_linux.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698