OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/bind.h" | 13 #include "base/bind.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
16 #include "base/path_service.h" | 16 #include "base/path_service.h" |
17 #include "base/stringprintf.h" | 17 #include "base/stringprintf.h" |
18 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
19 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
20 #include "chrome/common/chrome_paths.h" | 20 #include "chrome/common/chrome_paths.h" |
21 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
22 #include "chrome/common/logging_chrome.h" | 22 #include "chrome/common/logging_chrome.h" |
23 #include "chrome/common/nacl_cmd_line.h" | 23 #include "chrome/common/nacl_cmd_line.h" |
24 #include "chrome/common/nacl_messages.h" | 24 #include "chrome/common/nacl_messages.h" |
25 #include "chrome/common/render_messages.h" | 25 #include "chrome/common/render_messages.h" |
26 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" | 26 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" |
| 27 #include "content/public/browser/browser_child_process_host.h" |
| 28 #include "content/public/browser/child_process_data.h" |
27 #include "content/public/common/child_process_host.h" | 29 #include "content/public/common/child_process_host.h" |
28 #include "ipc/ipc_switches.h" | 30 #include "ipc/ipc_switches.h" |
29 #include "native_client/src/shared/imc/nacl_imc.h" | 31 #include "native_client/src/shared/imc/nacl_imc.h" |
30 | 32 |
31 #if defined(OS_POSIX) | 33 #if defined(OS_POSIX) |
32 #include "ipc/ipc_channel_posix.h" | 34 #include "ipc/ipc_channel_posix.h" |
33 #elif defined(OS_WIN) | 35 #elif defined(OS_WIN) |
34 #include "chrome/browser/nacl_host/nacl_broker_service_win.h" | 36 #include "chrome/browser/nacl_host/nacl_broker_service_win.h" |
35 #endif | 37 #endif |
36 | 38 |
37 using content::BrowserThread; | 39 using content::BrowserThread; |
| 40 using content::ChildProcessData; |
38 using content::ChildProcessHost; | 41 using content::ChildProcessHost; |
39 | 42 |
40 namespace { | 43 namespace { |
41 | 44 |
42 void SetCloseOnExec(nacl::Handle fd) { | 45 void SetCloseOnExec(nacl::Handle fd) { |
43 #if defined(OS_POSIX) | 46 #if defined(OS_POSIX) |
44 int flags = fcntl(fd, F_GETFD); | 47 int flags = fcntl(fd, F_GETFD); |
45 CHECK_NE(flags, -1); | 48 CHECK_NE(flags, -1); |
46 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | 49 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
47 CHECK_EQ(rc, 0); | 50 CHECK_EQ(rc, 0); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 }; | 105 }; |
103 | 106 |
104 #if defined(OS_WIN) | 107 #if defined(OS_WIN) |
105 static bool RunningOnWOW64() { | 108 static bool RunningOnWOW64() { |
106 return (base::win::OSInfo::GetInstance()->wow64_status() == | 109 return (base::win::OSInfo::GetInstance()->wow64_status() == |
107 base::win::OSInfo::WOW64_ENABLED); | 110 base::win::OSInfo::WOW64_ENABLED); |
108 } | 111 } |
109 #endif | 112 #endif |
110 | 113 |
111 NaClProcessHost::NaClProcessHost(const std::wstring& url) | 114 NaClProcessHost::NaClProcessHost(const std::wstring& url) |
112 : BrowserChildProcessHost(content::PROCESS_TYPE_NACL_LOADER), | 115 : reply_msg_(NULL), |
113 reply_msg_(NULL), | |
114 internal_(new NaClInternal()), | 116 internal_(new NaClInternal()), |
115 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 117 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
116 SetName(WideToUTF16Hack(url)); | 118 process_.reset(content::BrowserChildProcessHost::Create( |
| 119 content::PROCESS_TYPE_NACL_LOADER, this)); |
| 120 process_->SetName(WideToUTF16Hack(url)); |
117 } | 121 } |
118 | 122 |
119 NaClProcessHost::~NaClProcessHost() { | 123 NaClProcessHost::~NaClProcessHost() { |
120 int exit_code; | 124 int exit_code; |
121 GetChildTerminationStatus(&exit_code); | 125 process_->GetTerminationStatus(&exit_code); |
122 std::string message = | 126 std::string message = |
123 base::StringPrintf("NaCl process exited with status %i (0x%x)", | 127 base::StringPrintf("NaCl process exited with status %i (0x%x)", |
124 exit_code, exit_code); | 128 exit_code, exit_code); |
125 if (exit_code == 0) { | 129 if (exit_code == 0) { |
126 LOG(INFO) << message; | 130 LOG(INFO) << message; |
127 } else { | 131 } else { |
128 LOG(ERROR) << message; | 132 LOG(ERROR) << message; |
129 } | 133 } |
130 | 134 |
131 #if defined(OS_WIN) | 135 #if defined(OS_WIN) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 } | 231 } |
228 | 232 |
229 chrome_render_message_filter_ = chrome_render_message_filter; | 233 chrome_render_message_filter_ = chrome_render_message_filter; |
230 | 234 |
231 // On success, we take responsibility for sending the reply. | 235 // On success, we take responsibility for sending the reply. |
232 reply_msg_ = reply_msg; | 236 reply_msg_ = reply_msg; |
233 return true; | 237 return true; |
234 } | 238 } |
235 | 239 |
236 bool NaClProcessHost::LaunchSelLdr() { | 240 bool NaClProcessHost::LaunchSelLdr() { |
237 std::string channel_id = child_process_host()->CreateChannel(); | 241 std::string channel_id = process_->GetHost()->CreateChannel(); |
238 if (channel_id.empty()) | 242 if (channel_id.empty()) |
239 return false; | 243 return false; |
240 | 244 |
241 CommandLine::StringType nacl_loader_prefix; | 245 CommandLine::StringType nacl_loader_prefix; |
242 #if defined(OS_POSIX) | 246 #if defined(OS_POSIX) |
243 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative( | 247 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative( |
244 switches::kNaClLoaderCmdPrefix); | 248 switches::kNaClLoaderCmdPrefix); |
245 #endif // defined(OS_POSIX) | 249 #endif // defined(OS_POSIX) |
246 | 250 |
247 // Build command line for nacl. | 251 // Build command line for nacl. |
(...skipping 28 matching lines...) Expand all Loading... |
276 | 280 |
277 if (!nacl_loader_prefix.empty()) | 281 if (!nacl_loader_prefix.empty()) |
278 cmd_line->PrependWrapper(nacl_loader_prefix); | 282 cmd_line->PrependWrapper(nacl_loader_prefix); |
279 | 283 |
280 // On Windows we might need to start the broker process to launch a new loader | 284 // On Windows we might need to start the broker process to launch a new loader |
281 #if defined(OS_WIN) | 285 #if defined(OS_WIN) |
282 if (RunningOnWOW64()) { | 286 if (RunningOnWOW64()) { |
283 return NaClBrokerService::GetInstance()->LaunchLoader( | 287 return NaClBrokerService::GetInstance()->LaunchLoader( |
284 this, ASCIIToWide(channel_id)); | 288 this, ASCIIToWide(channel_id)); |
285 } else { | 289 } else { |
286 BrowserChildProcessHost::Launch(FilePath(), cmd_line); | 290 process_->Launch(FilePath(), cmd_line); |
287 } | 291 } |
288 #elif defined(OS_POSIX) | 292 #elif defined(OS_POSIX) |
289 BrowserChildProcessHost::Launch(nacl_loader_prefix.empty(), // use_zygote | 293 process_->Launch(nacl_loader_prefix.empty(), // use_zygote |
290 base::environment_vector(), | 294 base::environment_vector(), |
291 cmd_line); | 295 cmd_line); |
292 #endif | 296 #endif |
293 | 297 |
294 return true; | 298 return true; |
295 } | 299 } |
296 | 300 |
297 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { | 301 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { |
298 SetHandle(handle); | 302 process_->SetHandle(handle); |
299 OnProcessLaunched(); | 303 OnProcessLaunched(); |
300 } | 304 } |
301 | 305 |
302 void NaClProcessHost::OnProcessCrashed(int exit_code) { | 306 void NaClProcessHost::OnProcessCrashed(int exit_code) { |
303 std::string message = base::StringPrintf( | 307 std::string message = base::StringPrintf( |
304 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); | 308 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); |
305 LOG(ERROR) << message; | 309 LOG(ERROR) << message; |
306 } | 310 } |
307 | 311 |
308 namespace { | 312 namespace { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 #else | 466 #else |
463 // No need to dup the imc_handle - we don't pass it anywhere else so | 467 // No need to dup the imc_handle - we don't pass it anywhere else so |
464 // it cannot be closed. | 468 // it cannot be closed. |
465 nacl::FileDescriptor imc_handle; | 469 nacl::FileDescriptor imc_handle; |
466 imc_handle.fd = internal_->sockets_for_renderer[i]; | 470 imc_handle.fd = internal_->sockets_for_renderer[i]; |
467 imc_handle.auto_close = true; | 471 imc_handle.auto_close = true; |
468 handles_for_renderer.push_back(imc_handle); | 472 handles_for_renderer.push_back(imc_handle); |
469 #endif | 473 #endif |
470 } | 474 } |
471 | 475 |
| 476 const ChildProcessData& data = process_->GetData(); |
472 #if defined(OS_WIN) | 477 #if defined(OS_WIN) |
473 // Copy the process handle into the renderer process. | 478 // Copy the process handle into the renderer process. |
474 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 479 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
475 data().handle, | 480 data.handle, |
476 chrome_render_message_filter_->peer_handle(), | 481 chrome_render_message_filter_->peer_handle(), |
477 &nacl_process_handle, | 482 &nacl_process_handle, |
478 PROCESS_DUP_HANDLE, | 483 PROCESS_DUP_HANDLE, |
479 FALSE, | 484 FALSE, |
480 0)) { | 485 0)) { |
481 LOG(ERROR) << "DuplicateHandle() failed"; | 486 LOG(ERROR) << "DuplicateHandle() failed"; |
482 delete this; | 487 delete this; |
483 return; | 488 return; |
484 } | 489 } |
485 #else | 490 #else |
486 // We use pid as process handle on Posix | 491 // We use pid as process handle on Posix |
487 nacl_process_handle = data().handle; | 492 nacl_process_handle = data.handle; |
488 #endif | 493 #endif |
489 | 494 |
490 // Get the pid of the NaCl process | 495 // Get the pid of the NaCl process |
491 base::ProcessId nacl_process_id = base::GetProcId(data().handle); | 496 base::ProcessId nacl_process_id = base::GetProcId(data.handle); |
492 | 497 |
493 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | 498 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( |
494 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); | 499 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); |
495 chrome_render_message_filter_->Send(reply_msg_); | 500 chrome_render_message_filter_->Send(reply_msg_); |
496 chrome_render_message_filter_ = NULL; | 501 chrome_render_message_filter_ = NULL; |
497 reply_msg_ = NULL; | 502 reply_msg_ = NULL; |
498 internal_->sockets_for_renderer.clear(); | 503 internal_->sockets_for_renderer.clear(); |
499 | 504 |
500 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; | 505 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; |
501 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { | 506 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
502 if (!SendHandleToSelLdr(data().handle, | 507 if (!SendHandleToSelLdr(data.handle, |
503 internal_->sockets_for_sel_ldr[i], true, | 508 internal_->sockets_for_sel_ldr[i], true, |
504 &handles_for_sel_ldr)) { | 509 &handles_for_sel_ldr)) { |
505 delete this; | 510 delete this; |
506 return; | 511 return; |
507 } | 512 } |
508 } | 513 } |
509 | 514 |
510 // Send over the IRT file handle. We don't close our own copy! | 515 // Send over the IRT file handle. We don't close our own copy! |
511 if (!SendHandleToSelLdr( | 516 if (!SendHandleToSelLdr(data.handle, irt_file, false, &handles_for_sel_ldr)) { |
512 data().handle, irt_file, false, &handles_for_sel_ldr)) { | |
513 delete this; | 517 delete this; |
514 return; | 518 return; |
515 } | 519 } |
516 | 520 |
517 #if defined(OS_MACOSX) | 521 #if defined(OS_MACOSX) |
518 // For dynamic loading support, NaCl requires a file descriptor that | 522 // For dynamic loading support, NaCl requires a file descriptor that |
519 // was created in /tmp, since those created with shm_open() are not | 523 // was created in /tmp, since those created with shm_open() are not |
520 // mappable with PROT_EXEC. Rather than requiring an extra IPC | 524 // mappable with PROT_EXEC. Rather than requiring an extra IPC |
521 // round trip out of the sandbox, we create an FD here. | 525 // round trip out of the sandbox, we create an FD here. |
522 base::SharedMemory memory_buffer; | 526 base::SharedMemory memory_buffer; |
523 base::SharedMemoryCreateOptions options; | 527 base::SharedMemoryCreateOptions options; |
524 options.size = 1; | 528 options.size = 1; |
525 options.executable = true; | 529 options.executable = true; |
526 if (!memory_buffer.Create(options)) { | 530 if (!memory_buffer.Create(options)) { |
527 LOG(ERROR) << "Failed to allocate memory buffer"; | 531 LOG(ERROR) << "Failed to allocate memory buffer"; |
528 delete this; | 532 delete this; |
529 return; | 533 return; |
530 } | 534 } |
531 nacl::FileDescriptor memory_fd; | 535 nacl::FileDescriptor memory_fd; |
532 memory_fd.fd = dup(memory_buffer.handle().fd); | 536 memory_fd.fd = dup(memory_buffer.handle().fd); |
533 if (memory_fd.fd < 0) { | 537 if (memory_fd.fd < 0) { |
534 LOG(ERROR) << "Failed to dup() a file descriptor"; | 538 LOG(ERROR) << "Failed to dup() a file descriptor"; |
535 delete this; | 539 delete this; |
536 return; | 540 return; |
537 } | 541 } |
538 memory_fd.auto_close = true; | 542 memory_fd.auto_close = true; |
539 handles_for_sel_ldr.push_back(memory_fd); | 543 handles_for_sel_ldr.push_back(memory_fd); |
540 #endif | 544 #endif |
541 | 545 |
542 Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); | 546 process_->Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); |
543 internal_->sockets_for_sel_ldr.clear(); | 547 internal_->sockets_for_sel_ldr.clear(); |
544 } | 548 } |
545 | 549 |
546 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { | 550 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { |
547 NOTREACHED() << "Invalid message with type = " << msg.type(); | 551 NOTREACHED() << "Invalid message with type = " << msg.type(); |
548 return false; | 552 return false; |
549 } | 553 } |
OLD | NEW |