OLD | NEW |
---|---|
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 #include "chrome/browser/nacl_host/nacl_process_host.h" | 5 #include "chrome/browser/nacl_host/nacl_process_host.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 int flags = DUPLICATE_SAME_ACCESS; | 95 int flags = DUPLICATE_SAME_ACCESS; |
96 if (close_source) | 96 if (close_source) |
97 flags |= DUPLICATE_CLOSE_SOURCE; | 97 flags |= DUPLICATE_CLOSE_SOURCE; |
98 if (!DuplicateHandle(GetCurrentProcess(), | 98 if (!DuplicateHandle(GetCurrentProcess(), |
99 reinterpret_cast<HANDLE>(sourceh), | 99 reinterpret_cast<HANDLE>(sourceh), |
100 processh, | 100 processh, |
101 &channel, | 101 &channel, |
102 0, // Unused given DUPLICATE_SAME_ACCESS. | 102 0, // Unused given DUPLICATE_SAME_ACCESS. |
103 FALSE, | 103 FALSE, |
104 flags)) { | 104 flags)) { |
105 DLOG(ERROR) << "DuplicateHandle() failed"; | 105 LOG(ERROR) << "DuplicateHandle() failed"; |
106 return false; | 106 return false; |
107 } | 107 } |
108 handles_for_sel_ldr->push_back( | 108 handles_for_sel_ldr->push_back( |
109 reinterpret_cast<nacl::FileDescriptor>(channel)); | 109 reinterpret_cast<nacl::FileDescriptor>(channel)); |
110 #else | 110 #else |
111 nacl::FileDescriptor channel; | 111 nacl::FileDescriptor channel; |
112 channel.fd = sourceh; | 112 channel.fd = sourceh; |
113 channel.auto_close = close_source; | 113 channel.auto_close = close_source; |
114 handles_for_sel_ldr->push_back(channel); | 114 handles_for_sel_ldr->push_back(channel); |
115 #endif | 115 #endif |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 scoped_refptr<ExtensionInfoMap> extension_info_map) { | 263 scoped_refptr<ExtensionInfoMap> extension_info_map) { |
264 chrome_render_message_filter_ = chrome_render_message_filter; | 264 chrome_render_message_filter_ = chrome_render_message_filter; |
265 reply_msg_ = reply_msg; | 265 reply_msg_ = reply_msg; |
266 extension_info_map_ = extension_info_map; | 266 extension_info_map_ = extension_info_map; |
267 | 267 |
268 // Start getting the IRT open asynchronously while we launch the NaCl process. | 268 // Start getting the IRT open asynchronously while we launch the NaCl process. |
269 // We'll make sure this actually finished in StartWithLaunchedProcess, below. | 269 // We'll make sure this actually finished in StartWithLaunchedProcess, below. |
270 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 270 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
271 nacl_browser->EnsureAllResourcesAvailable(); | 271 nacl_browser->EnsureAllResourcesAvailable(); |
272 if (!nacl_browser->IsOk()) { | 272 if (!nacl_browser->IsOk()) { |
273 DLOG(ERROR) << "Cannot launch NaCl process"; | 273 LOG(ERROR) << "NaCl process launch failed: could not find all the " |
274 "resources needed to launch the process."; | |
Mark Seaborn
2013/01/16 00:27:54
This is being picky, but most log messages in Chro
Nick Bray (chromium)
2013/01/16 05:54:52
Done.
| |
274 delete this; | 275 delete this; |
275 return; | 276 return; |
276 } | 277 } |
277 | 278 |
278 // Rather than creating a socket pair in the renderer, and passing | 279 // Rather than creating a socket pair in the renderer, and passing |
279 // one side through the browser to sel_ldr, socket pairs are created | 280 // one side through the browser to sel_ldr, socket pairs are created |
280 // in the browser and then passed to the renderer and sel_ldr. | 281 // in the browser and then passed to the renderer and sel_ldr. |
281 // | 282 // |
282 // This is mainly for the benefit of Windows, where sockets cannot | 283 // This is mainly for the benefit of Windows, where sockets cannot |
283 // be passed in messages, but are copied via DuplicateHandle(). | 284 // be passed in messages, but are copied via DuplicateHandle(). |
284 // This means the sandboxed renderer cannot send handles to the | 285 // This means the sandboxed renderer cannot send handles to the |
285 // browser process. | 286 // browser process. |
286 | 287 |
287 nacl::Handle pair[2]; | 288 nacl::Handle pair[2]; |
288 // Create a connected socket | 289 // Create a connected socket |
289 if (nacl::SocketPair(pair) == -1) { | 290 if (nacl::SocketPair(pair) == -1) { |
291 LOG(ERROR) << "NaCl process launch failed: could not create a socket pair."; | |
290 delete this; | 292 delete this; |
291 return; | 293 return; |
292 } | 294 } |
293 internal_->socket_for_renderer = pair[0]; | 295 internal_->socket_for_renderer = pair[0]; |
294 internal_->socket_for_sel_ldr = pair[1]; | 296 internal_->socket_for_sel_ldr = pair[1]; |
295 SetCloseOnExec(pair[0]); | 297 SetCloseOnExec(pair[0]); |
296 SetCloseOnExec(pair[1]); | 298 SetCloseOnExec(pair[1]); |
297 | 299 |
298 // Launch the process | 300 // Launch the process |
299 if (!LaunchSelLdr()) { | 301 if (!LaunchSelLdr()) { |
(...skipping 14 matching lines...) Expand all Loading... | |
314 base::kProcessAccessDuplicateHandle | | 316 base::kProcessAccessDuplicateHandle | |
315 base::kProcessAccessQueryInformation | | 317 base::kProcessAccessQueryInformation | |
316 base::kProcessAccessWaitForTermination, | 318 base::kProcessAccessWaitForTermination, |
317 &process)) { | 319 &process)) { |
318 process_->SetHandle(process); | 320 process_->SetHandle(process); |
319 if (!StartWithLaunchedProcess()) { | 321 if (!StartWithLaunchedProcess()) { |
320 delete this; | 322 delete this; |
321 return; | 323 return; |
322 } | 324 } |
323 } else { | 325 } else { |
324 DLOG(ERROR) << "Failed to get process handle"; | 326 LOG(ERROR) << "Failed to get process handle"; |
325 } | 327 } |
326 } | 328 } |
327 } | 329 } |
328 #else | 330 #else |
329 void NaClProcessHost::OnChannelConnected(int32 peer_pid) { | 331 void NaClProcessHost::OnChannelConnected(int32 peer_pid) { |
330 } | 332 } |
331 #endif | 333 #endif |
332 | 334 |
333 #if defined(OS_WIN) | 335 #if defined(OS_WIN) |
334 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { | 336 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
483 manifest_url_.SchemeIs(extensions::kExtensionScheme)) { | 485 manifest_url_.SchemeIs(extensions::kExtensionScheme)) { |
484 std::string path = manifest_url_.path(); | 486 std::string path = manifest_url_.path(); |
485 TrimString(path, "/", &path); // Remove first slash | 487 TrimString(path, "/", &path); // Remove first slash |
486 return extension->path().AppendASCII(path); | 488 return extension->path().AppendASCII(path); |
487 } | 489 } |
488 return FilePath(); | 490 return FilePath(); |
489 } | 491 } |
490 | 492 |
491 bool NaClProcessHost::LaunchSelLdr() { | 493 bool NaClProcessHost::LaunchSelLdr() { |
492 std::string channel_id = process_->GetHost()->CreateChannel(); | 494 std::string channel_id = process_->GetHost()->CreateChannel(); |
493 if (channel_id.empty()) | 495 if (channel_id.empty()) { |
496 LOG(ERROR) << "NaCl process launch failed: could not create channel."; | |
494 return false; | 497 return false; |
498 } | |
495 | 499 |
496 CommandLine::StringType nacl_loader_prefix; | 500 CommandLine::StringType nacl_loader_prefix; |
497 #if defined(OS_POSIX) | 501 #if defined(OS_POSIX) |
498 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative( | 502 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative( |
499 switches::kNaClLoaderCmdPrefix); | 503 switches::kNaClLoaderCmdPrefix); |
500 #endif // defined(OS_POSIX) | 504 #endif // defined(OS_POSIX) |
501 | 505 |
502 // Build command line for nacl. | 506 // Build command line for nacl. |
503 | 507 |
504 #if defined(OS_MACOSX) | 508 #if defined(OS_MACOSX) |
(...skipping 12 matching lines...) Expand all Loading... | |
517 #endif | 521 #endif |
518 | 522 |
519 FilePath exe_path = ChildProcessHost::GetChildPath(flags); | 523 FilePath exe_path = ChildProcessHost::GetChildPath(flags); |
520 if (exe_path.empty()) | 524 if (exe_path.empty()) |
521 return false; | 525 return false; |
522 | 526 |
523 #if defined(OS_WIN) | 527 #if defined(OS_WIN) |
524 // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe | 528 // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe |
525 if (RunningOnWOW64()) { | 529 if (RunningOnWOW64()) { |
526 FilePath module_path; | 530 FilePath module_path; |
527 if (!PathService::Get(base::FILE_MODULE, &module_path)) | 531 if (!PathService::Get(base::FILE_MODULE, &module_path)) { |
532 LOG(ERROR) << "NaCl process launch failed: could not resolve module."; | |
528 return false; | 533 return false; |
534 } | |
529 exe_path = module_path.DirName().Append(chrome::kNaClAppName); | 535 exe_path = module_path.DirName().Append(chrome::kNaClAppName); |
530 } | 536 } |
531 #endif | 537 #endif |
532 | 538 |
533 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path)); | 539 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path)); |
534 nacl::CopyNaClCommandLineArguments(cmd_line.get()); | 540 nacl::CopyNaClCommandLineArguments(cmd_line.get()); |
535 | 541 |
536 cmd_line->AppendSwitchASCII(switches::kProcessType, | 542 cmd_line->AppendSwitchASCII(switches::kProcessType, |
537 switches::kNaClLoaderProcess); | 543 switches::kNaClLoaderProcess); |
538 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); | 544 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
(...skipping 20 matching lines...) Expand all Loading... | |
559 // call OnProcessLaunched. | 565 // call OnProcessLaunched. |
560 return base::LaunchProcess(*gdb_cmd_line, base::LaunchOptions(), NULL); | 566 return base::LaunchProcess(*gdb_cmd_line, base::LaunchOptions(), NULL); |
561 #elif defined(OS_LINUX) | 567 #elif defined(OS_LINUX) |
562 wait_for_nacl_gdb_ = true; | 568 wait_for_nacl_gdb_ = true; |
563 #endif | 569 #endif |
564 } | 570 } |
565 | 571 |
566 // On Windows we might need to start the broker process to launch a new loader | 572 // On Windows we might need to start the broker process to launch a new loader |
567 #if defined(OS_WIN) | 573 #if defined(OS_WIN) |
568 if (RunningOnWOW64()) { | 574 if (RunningOnWOW64()) { |
569 return NaClBrokerService::GetInstance()->LaunchLoader( | 575 if (!NaClBrokerService::GetInstance()->LaunchLoader( |
570 weak_factory_.GetWeakPtr(), channel_id); | 576 weak_factory_.GetWeakPtr(), channel_id)) { |
Mark Seaborn
2013/01/16 00:27:54
Indent function argument
Nick Bray (chromium)
2013/01/16 05:54:52
How? This is technically indented 2x relative to
Mark Seaborn
2013/01/16 16:03:51
You should write
if (!NaClBrokerService::GetInsta
| |
577 LOG(ERROR) << "NaCl process launch failed: broker service did not launch " | |
578 "process."; | |
579 return false; | |
580 } | |
571 } else { | 581 } else { |
572 process_->Launch(FilePath(), cmd_line.release()); | 582 process_->Launch(FilePath(), cmd_line.release()); |
573 } | 583 } |
574 #elif defined(OS_POSIX) | 584 #elif defined(OS_POSIX) |
575 process_->Launch(nacl_loader_prefix.empty(), // use_zygote | 585 process_->Launch(nacl_loader_prefix.empty(), // use_zygote |
576 base::EnvironmentVector(), | 586 base::EnvironmentVector(), |
577 cmd_line.release()); | 587 cmd_line.release()); |
578 #endif | 588 #endif |
579 | 589 |
580 return true; | 590 return true; |
(...skipping 18 matching lines...) Expand all Loading... | |
599 } | 609 } |
600 | 610 |
601 void NaClProcessHost::OnProcessLaunched() { | 611 void NaClProcessHost::OnProcessLaunched() { |
602 if (!StartWithLaunchedProcess()) | 612 if (!StartWithLaunchedProcess()) |
603 delete this; | 613 delete this; |
604 } | 614 } |
605 | 615 |
606 // Called when the NaClBrowser singleton has been fully initialized. | 616 // Called when the NaClBrowser singleton has been fully initialized. |
607 void NaClProcessHost::OnResourcesReady() { | 617 void NaClProcessHost::OnResourcesReady() { |
608 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 618 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
609 if (!nacl_browser->IsReady() || !SendStart()) { | 619 if (!nacl_browser->IsReady()) { |
610 DLOG(ERROR) << "Cannot launch NaCl process"; | 620 LOG(ERROR) << "NaCl process launch failed: could not aquire shared " |
Mark Seaborn
2013/01/16 00:27:54
"acquire"
Nick Bray (chromium)
2013/01/16 05:54:52
Done.
| |
621 "resources needed by NaCl."; | |
622 delete this; | |
623 } else if (!SendStart()) { | |
611 delete this; | 624 delete this; |
612 } | 625 } |
613 } | 626 } |
614 | 627 |
615 bool NaClProcessHost::ReplyToRenderer( | 628 bool NaClProcessHost::ReplyToRenderer( |
616 const IPC::ChannelHandle& channel_handle) { | 629 const IPC::ChannelHandle& channel_handle) { |
617 nacl::FileDescriptor handle_for_renderer; | 630 nacl::FileDescriptor handle_for_renderer; |
618 #if defined(OS_WIN) | 631 #if defined(OS_WIN) |
619 // Copy the handle into the renderer process. | 632 // Copy the handle into the renderer process. |
620 HANDLE handle_in_renderer; | 633 HANDLE handle_in_renderer; |
621 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 634 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
622 reinterpret_cast<HANDLE>( | 635 reinterpret_cast<HANDLE>( |
623 internal_->socket_for_renderer), | 636 internal_->socket_for_renderer), |
624 chrome_render_message_filter_->peer_handle(), | 637 chrome_render_message_filter_->peer_handle(), |
625 &handle_in_renderer, | 638 &handle_in_renderer, |
626 0, // Unused given DUPLICATE_SAME_ACCESS. | 639 0, // Unused given DUPLICATE_SAME_ACCESS. |
627 FALSE, | 640 FALSE, |
628 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 641 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
629 DLOG(ERROR) << "DuplicateHandle() failed"; | 642 LOG(ERROR) << "DuplicateHandle() failed"; |
630 return false; | 643 return false; |
631 } | 644 } |
632 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>( | 645 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>( |
633 handle_in_renderer); | 646 handle_in_renderer); |
634 #else | 647 #else |
635 // No need to dup the imc_handle - we don't pass it anywhere else so | 648 // No need to dup the imc_handle - we don't pass it anywhere else so |
636 // it cannot be closed. | 649 // it cannot be closed. |
637 nacl::FileDescriptor imc_handle; | 650 nacl::FileDescriptor imc_handle; |
638 imc_handle.fd = internal_->socket_for_renderer; | 651 imc_handle.fd = internal_->socket_for_renderer; |
639 imc_handle.auto_close = true; | 652 imc_handle.auto_close = true; |
640 handle_for_renderer = imc_handle; | 653 handle_for_renderer = imc_handle; |
641 #endif | 654 #endif |
642 | 655 |
643 #if defined(OS_WIN) | 656 #if defined(OS_WIN) |
644 // If we are on 64-bit Windows, the NaCl process's sandbox is | 657 // If we are on 64-bit Windows, the NaCl process's sandbox is |
645 // managed by a different process from the renderer's sandbox. We | 658 // managed by a different process from the renderer's sandbox. We |
646 // need to inform the renderer's sandbox about the NaCl process so | 659 // need to inform the renderer's sandbox about the NaCl process so |
647 // that the renderer can send handles to the NaCl process using | 660 // that the renderer can send handles to the NaCl process using |
648 // BrokerDuplicateHandle(). | 661 // BrokerDuplicateHandle(). |
649 if (RunningOnWOW64()) { | 662 if (RunningOnWOW64()) { |
650 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { | 663 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { |
651 DLOG(ERROR) << "Failed to add NaCl process PID"; | 664 LOG(ERROR) << "Failed to add NaCl process PID"; |
652 return false; | 665 return false; |
653 } | 666 } |
654 } | 667 } |
655 #endif | 668 #endif |
656 | 669 |
657 const ChildProcessData& data = process_->GetData(); | 670 const ChildProcessData& data = process_->GetData(); |
658 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | 671 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( |
659 reply_msg_, handle_for_renderer, | 672 reply_msg_, handle_for_renderer, |
660 channel_handle, base::GetProcId(data.handle), data.id); | 673 channel_handle, base::GetProcId(data.handle), data.id); |
661 chrome_render_message_filter_->Send(reply_msg_); | 674 chrome_render_message_filter_->Send(reply_msg_); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
845 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 858 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
846 | 859 |
847 if (nacl_browser->IsReady()) { | 860 if (nacl_browser->IsReady()) { |
848 return SendStart(); | 861 return SendStart(); |
849 } else if (nacl_browser->IsOk()) { | 862 } else if (nacl_browser->IsOk()) { |
850 nacl_browser->WaitForResources( | 863 nacl_browser->WaitForResources( |
851 base::Bind(&NaClProcessHost::OnResourcesReady, | 864 base::Bind(&NaClProcessHost::OnResourcesReady, |
852 weak_factory_.GetWeakPtr())); | 865 weak_factory_.GetWeakPtr())); |
853 return true; | 866 return true; |
854 } else { | 867 } else { |
868 LOG(ERROR) << "NaCl process failed to launch: previously failed to aquire " | |
Mark Seaborn
2013/01/16 00:27:54
"acquire"
Nick Bray (chromium)
2013/01/16 05:54:52
Done.
| |
869 "shared resources."; | |
855 return false; | 870 return false; |
856 } | 871 } |
857 } | 872 } |
858 | 873 |
859 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, | 874 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, |
860 bool* result) { | 875 bool* result) { |
861 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 876 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
862 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); | 877 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); |
863 } | 878 } |
864 | 879 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
927 } else { | 942 } else { |
928 NaClStartDebugExceptionHandlerThread( | 943 NaClStartDebugExceptionHandlerThread( |
929 process_handle.Take(), info, | 944 process_handle.Take(), info, |
930 base::MessageLoopProxy::current(), | 945 base::MessageLoopProxy::current(), |
931 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 946 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
932 weak_factory_.GetWeakPtr())); | 947 weak_factory_.GetWeakPtr())); |
933 return true; | 948 return true; |
934 } | 949 } |
935 } | 950 } |
936 #endif | 951 #endif |
OLD | NEW |