OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #include "chrome/browser/nacl_host/nacl_process_host.h" | 7 #include "chrome/browser/nacl_host/nacl_process_host.h" |
8 | 8 |
9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
11 #endif | 11 #endif |
12 | 12 |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/metrics/nacl_histogram.h" | 14 #include "base/metrics/nacl_histogram.h" |
15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
16 #include "chrome/browser/renderer_host/render_message_filter.h" | 16 #include "chrome/browser/renderer_host/render_message_filter.h" |
17 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" |
18 #include "chrome/common/logging_chrome.h" | 18 #include "chrome/common/logging_chrome.h" |
19 #include "chrome/common/nacl_cmd_line.h" | 19 #include "chrome/common/nacl_cmd_line.h" |
20 #include "chrome/common/nacl_messages.h" | 20 #include "chrome/common/nacl_messages.h" |
21 #include "chrome/common/render_messages.h" | 21 #include "chrome/common/render_messages.h" |
22 #include "ipc/ipc_switches.h" | 22 #include "ipc/ipc_switches.h" |
| 23 #include "native_client/src/shared/imc/nacl_imc.h" |
23 | 24 |
24 #if defined(OS_POSIX) | 25 #if defined(OS_POSIX) |
25 #include "ipc/ipc_channel_posix.h" | 26 #include "ipc/ipc_channel_posix.h" |
26 #elif defined(OS_WIN) | 27 #elif defined(OS_WIN) |
27 #include "chrome/browser/nacl_host/nacl_broker_service_win.h" | 28 #include "chrome/browser/nacl_host/nacl_broker_service_win.h" |
28 #endif | 29 #endif |
29 | 30 |
30 namespace { | 31 namespace { |
31 | 32 |
32 #if !defined(DISABLE_NACL) | 33 #if !defined(DISABLE_NACL) |
33 void SetCloseOnExec(nacl::Handle fd) { | 34 void SetCloseOnExec(nacl::Handle fd) { |
34 #if defined(OS_POSIX) | 35 #if defined(OS_POSIX) |
35 int flags = fcntl(fd, F_GETFD); | 36 int flags = fcntl(fd, F_GETFD); |
36 CHECK(flags != -1); | 37 CHECK(flags != -1); |
37 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | 38 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
38 CHECK(rc == 0); | 39 CHECK(rc == 0); |
39 #endif | 40 #endif |
40 } | 41 } |
41 #endif | 42 #endif |
42 | 43 |
43 } // namespace | 44 } // namespace |
44 | 45 |
| 46 struct NaClProcessHost::NaClInternal { |
| 47 std::vector<nacl::Handle> sockets_for_renderer; |
| 48 std::vector<nacl::Handle> sockets_for_sel_ldr; |
| 49 }; |
| 50 |
45 NaClProcessHost::NaClProcessHost( | 51 NaClProcessHost::NaClProcessHost( |
46 ResourceDispatcherHost *resource_dispatcher_host, | 52 ResourceDispatcherHost *resource_dispatcher_host, |
47 const std::wstring& url) | 53 const std::wstring& url) |
48 : BrowserChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host), | 54 : BrowserChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host), |
49 resource_dispatcher_host_(resource_dispatcher_host), | 55 resource_dispatcher_host_(resource_dispatcher_host), |
50 reply_msg_(NULL), | 56 reply_msg_(NULL), |
| 57 internal_(new NaClInternal()), |
51 running_on_wow64_(false) { | 58 running_on_wow64_(false) { |
52 set_name(url); | 59 set_name(url); |
53 #if defined(OS_WIN) | 60 #if defined(OS_WIN) |
54 CheckIsWow64(); | 61 CheckIsWow64(); |
55 #endif | 62 #endif |
56 } | 63 } |
57 | 64 |
58 NaClProcessHost::~NaClProcessHost() { | 65 NaClProcessHost::~NaClProcessHost() { |
59 if (!reply_msg_) | 66 if (!reply_msg_) |
60 return; | 67 return; |
61 | 68 |
62 // nacl::Close() is not available at link time if DISABLE_NACL is | 69 // nacl::Close() is not available at link time if DISABLE_NACL is |
63 // defined, but we still compile a bunch of other code from this | 70 // defined, but we still compile a bunch of other code from this |
64 // file anyway. TODO(mseaborn): Make this less messy. | 71 // file anyway. TODO(mseaborn): Make this less messy. |
65 #ifndef DISABLE_NACL | 72 #ifndef DISABLE_NACL |
66 for (size_t i = 0; i < sockets_for_renderer_.size(); i++) { | 73 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
67 nacl::Close(sockets_for_renderer_[i]); | 74 nacl::Close(internal_->sockets_for_renderer[i]); |
68 } | 75 } |
69 for (size_t i = 0; i < sockets_for_sel_ldr_.size(); i++) { | 76 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
70 nacl::Close(sockets_for_sel_ldr_[i]); | 77 nacl::Close(internal_->sockets_for_sel_ldr[i]); |
71 } | 78 } |
72 #endif | 79 #endif |
73 | 80 |
74 // OnProcessLaunched didn't get called because the process couldn't launch. | 81 // OnProcessLaunched didn't get called because the process couldn't launch. |
75 // Don't keep the renderer hanging. | 82 // Don't keep the renderer hanging. |
76 reply_msg_->set_reply_error(); | 83 reply_msg_->set_reply_error(); |
77 render_message_filter_->Send(reply_msg_); | 84 render_message_filter_->Send(reply_msg_); |
78 } | 85 } |
79 | 86 |
80 bool NaClProcessHost::Launch(RenderMessageFilter* render_message_filter, | 87 bool NaClProcessHost::Launch(RenderMessageFilter* render_message_filter, |
(...skipping 17 matching lines...) Expand all Loading... |
98 // This is mainly for the benefit of Windows, where sockets cannot | 105 // This is mainly for the benefit of Windows, where sockets cannot |
99 // be passed in messages, but are copied via DuplicateHandle(). | 106 // be passed in messages, but are copied via DuplicateHandle(). |
100 // This means the sandboxed renderer cannot send handles to the | 107 // This means the sandboxed renderer cannot send handles to the |
101 // browser process. | 108 // browser process. |
102 | 109 |
103 for (int i = 0; i < socket_count; i++) { | 110 for (int i = 0; i < socket_count; i++) { |
104 nacl::Handle pair[2]; | 111 nacl::Handle pair[2]; |
105 // Create a connected socket | 112 // Create a connected socket |
106 if (nacl::SocketPair(pair) == -1) | 113 if (nacl::SocketPair(pair) == -1) |
107 return false; | 114 return false; |
108 sockets_for_renderer_.push_back(pair[0]); | 115 internal_->sockets_for_renderer.push_back(pair[0]); |
109 sockets_for_sel_ldr_.push_back(pair[1]); | 116 internal_->sockets_for_sel_ldr.push_back(pair[1]); |
110 SetCloseOnExec(pair[0]); | 117 SetCloseOnExec(pair[0]); |
111 SetCloseOnExec(pair[1]); | 118 SetCloseOnExec(pair[1]); |
112 } | 119 } |
113 | 120 |
114 // Launch the process | 121 // Launch the process |
115 if (!LaunchSelLdr()) { | 122 if (!LaunchSelLdr()) { |
116 return false; | 123 return false; |
117 } | 124 } |
118 UmaNaclHistogramEnumeration(NACL_STARTED); | 125 UmaNaclHistogramEnumeration(NACL_STARTED); |
119 render_message_filter_ = render_message_filter; | 126 render_message_filter_ = render_message_filter; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 #if defined(OS_WIN) | 183 #if defined(OS_WIN) |
177 NaClBrokerService::GetInstance()->OnLoaderDied(); | 184 NaClBrokerService::GetInstance()->OnLoaderDied(); |
178 #endif | 185 #endif |
179 BrowserChildProcessHost::OnChildDied(); | 186 BrowserChildProcessHost::OnChildDied(); |
180 } | 187 } |
181 | 188 |
182 void NaClProcessHost::OnProcessLaunched() { | 189 void NaClProcessHost::OnProcessLaunched() { |
183 std::vector<nacl::FileDescriptor> handles_for_renderer; | 190 std::vector<nacl::FileDescriptor> handles_for_renderer; |
184 base::ProcessHandle nacl_process_handle; | 191 base::ProcessHandle nacl_process_handle; |
185 | 192 |
186 for (size_t i = 0; i < sockets_for_renderer_.size(); i++) { | 193 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
187 #if defined(OS_WIN) | 194 #if defined(OS_WIN) |
188 // Copy the handle into the renderer process. | 195 // Copy the handle into the renderer process. |
189 HANDLE handle_in_renderer; | 196 HANDLE handle_in_renderer; |
190 DuplicateHandle(base::GetCurrentProcessHandle(), | 197 DuplicateHandle(base::GetCurrentProcessHandle(), |
191 reinterpret_cast<HANDLE>(sockets_for_renderer_[i]), | 198 reinterpret_cast<HANDLE>( |
| 199 internal_->sockets_for_renderer[i]), |
192 render_message_filter_->peer_handle(), | 200 render_message_filter_->peer_handle(), |
193 &handle_in_renderer, | 201 &handle_in_renderer, |
194 GENERIC_READ | GENERIC_WRITE, | 202 GENERIC_READ | GENERIC_WRITE, |
195 FALSE, | 203 FALSE, |
196 DUPLICATE_CLOSE_SOURCE); | 204 DUPLICATE_CLOSE_SOURCE); |
197 handles_for_renderer.push_back( | 205 handles_for_renderer.push_back( |
198 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); | 206 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); |
199 #else | 207 #else |
200 // No need to dup the imc_handle - we don't pass it anywhere else so | 208 // No need to dup the imc_handle - we don't pass it anywhere else so |
201 // it cannot be closed. | 209 // it cannot be closed. |
202 nacl::FileDescriptor imc_handle; | 210 nacl::FileDescriptor imc_handle; |
203 imc_handle.fd = sockets_for_renderer_[i]; | 211 imc_handle.fd = internal_->sockets_for_renderer[i]; |
204 imc_handle.auto_close = true; | 212 imc_handle.auto_close = true; |
205 handles_for_renderer.push_back(imc_handle); | 213 handles_for_renderer.push_back(imc_handle); |
206 #endif | 214 #endif |
207 } | 215 } |
208 | 216 |
209 #if defined(OS_WIN) | 217 #if defined(OS_WIN) |
210 // Copy the process handle into the renderer process. | 218 // Copy the process handle into the renderer process. |
211 DuplicateHandle(base::GetCurrentProcessHandle(), | 219 DuplicateHandle(base::GetCurrentProcessHandle(), |
212 handle(), | 220 handle(), |
213 render_message_filter_->peer_handle(), | 221 render_message_filter_->peer_handle(), |
214 &nacl_process_handle, | 222 &nacl_process_handle, |
215 PROCESS_DUP_HANDLE, | 223 PROCESS_DUP_HANDLE, |
216 FALSE, | 224 FALSE, |
217 0); | 225 0); |
218 #else | 226 #else |
219 // We use pid as process handle on Posix | 227 // We use pid as process handle on Posix |
220 nacl_process_handle = handle(); | 228 nacl_process_handle = handle(); |
221 #endif | 229 #endif |
222 | 230 |
223 // Get the pid of the NaCl process | 231 // Get the pid of the NaCl process |
224 base::ProcessId nacl_process_id = base::GetProcId(handle()); | 232 base::ProcessId nacl_process_id = base::GetProcId(handle()); |
225 | 233 |
226 ViewHostMsg_LaunchNaCl::WriteReplyParams( | 234 ViewHostMsg_LaunchNaCl::WriteReplyParams( |
227 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); | 235 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); |
228 render_message_filter_->Send(reply_msg_); | 236 render_message_filter_->Send(reply_msg_); |
229 render_message_filter_ = NULL; | 237 render_message_filter_ = NULL; |
230 reply_msg_ = NULL; | 238 reply_msg_ = NULL; |
231 sockets_for_renderer_.clear(); | 239 internal_->sockets_for_renderer.clear(); |
232 | 240 |
233 SendStartMessage(); | 241 SendStartMessage(); |
234 } | 242 } |
235 | 243 |
236 void NaClProcessHost::SendStartMessage() { | 244 void NaClProcessHost::SendStartMessage() { |
237 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; | 245 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; |
238 for (size_t i = 0; i < sockets_for_sel_ldr_.size(); i++) { | 246 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
239 #if defined(OS_WIN) | 247 #if defined(OS_WIN) |
240 HANDLE channel; | 248 HANDLE channel; |
241 if (!DuplicateHandle(GetCurrentProcess(), | 249 if (!DuplicateHandle(GetCurrentProcess(), |
242 reinterpret_cast<HANDLE>(sockets_for_sel_ldr_[i]), | 250 reinterpret_cast<HANDLE>( |
| 251 internal_->sockets_for_sel_ldr[i]), |
243 handle(), | 252 handle(), |
244 &channel, | 253 &channel, |
245 GENERIC_READ | GENERIC_WRITE, | 254 GENERIC_READ | GENERIC_WRITE, |
246 FALSE, DUPLICATE_CLOSE_SOURCE)) { | 255 FALSE, DUPLICATE_CLOSE_SOURCE)) { |
247 return; | 256 return; |
248 } | 257 } |
249 handles_for_sel_ldr.push_back( | 258 handles_for_sel_ldr.push_back( |
250 reinterpret_cast<nacl::FileDescriptor>(channel)); | 259 reinterpret_cast<nacl::FileDescriptor>(channel)); |
251 #else | 260 #else |
252 nacl::FileDescriptor channel; | 261 nacl::FileDescriptor channel; |
253 channel.fd = dup(sockets_for_sel_ldr_[i]); | 262 channel.fd = dup(internal_->sockets_for_sel_ldr[i]); |
254 if (channel.fd < 0) { | 263 if (channel.fd < 0) { |
255 LOG(ERROR) << "Failed to dup() a file descriptor"; | 264 LOG(ERROR) << "Failed to dup() a file descriptor"; |
256 return; | 265 return; |
257 } | 266 } |
258 channel.auto_close = true; | 267 channel.auto_close = true; |
259 handles_for_sel_ldr.push_back(channel); | 268 handles_for_sel_ldr.push_back(channel); |
260 #endif | 269 #endif |
261 } | 270 } |
262 | 271 |
263 #if defined(OS_MACOSX) | 272 #if defined(OS_MACOSX) |
(...skipping 10 matching lines...) Expand all Loading... |
274 memory_fd.fd = dup(memory_buffer.handle().fd); | 283 memory_fd.fd = dup(memory_buffer.handle().fd); |
275 if (memory_fd.fd < 0) { | 284 if (memory_fd.fd < 0) { |
276 LOG(ERROR) << "Failed to dup() a file descriptor"; | 285 LOG(ERROR) << "Failed to dup() a file descriptor"; |
277 return; | 286 return; |
278 } | 287 } |
279 memory_fd.auto_close = true; | 288 memory_fd.auto_close = true; |
280 handles_for_sel_ldr.push_back(memory_fd); | 289 handles_for_sel_ldr.push_back(memory_fd); |
281 #endif | 290 #endif |
282 | 291 |
283 Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); | 292 Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); |
284 sockets_for_sel_ldr_.clear(); | 293 internal_->sockets_for_sel_ldr.clear(); |
285 } | 294 } |
286 | 295 |
287 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { | 296 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { |
288 NOTREACHED() << "Invalid message with type = " << msg.type(); | 297 NOTREACHED() << "Invalid message with type = " << msg.type(); |
289 return false; | 298 return false; |
290 } | 299 } |
291 | 300 |
292 bool NaClProcessHost::CanShutdown() { | 301 bool NaClProcessHost::CanShutdown() { |
293 return true; | 302 return true; |
294 } | 303 } |
(...skipping 11 matching lines...) Expand all Loading... |
306 if (fnIsWow64Process != NULL) { | 315 if (fnIsWow64Process != NULL) { |
307 BOOL bIsWow64 = FALSE; | 316 BOOL bIsWow64 = FALSE; |
308 if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { | 317 if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { |
309 if (bIsWow64) { | 318 if (bIsWow64) { |
310 running_on_wow64_ = true; | 319 running_on_wow64_ = true; |
311 } | 320 } |
312 } | 321 } |
313 } | 322 } |
314 } | 323 } |
315 #endif | 324 #endif |
OLD | NEW |