Chromium Code Reviews| 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 handles_for_sel_ldr->push_back(channel); | 103 handles_for_sel_ldr->push_back(channel); |
| 104 #endif | 104 #endif |
| 105 return true; | 105 return true; |
| 106 } | 106 } |
| 107 | 107 |
| 108 } // namespace | 108 } // namespace |
| 109 | 109 |
| 110 struct NaClProcessHost::NaClInternal { | 110 struct NaClProcessHost::NaClInternal { |
| 111 std::vector<nacl::Handle> sockets_for_renderer; | 111 std::vector<nacl::Handle> sockets_for_renderer; |
| 112 std::vector<nacl::Handle> sockets_for_sel_ldr; | 112 std::vector<nacl::Handle> sockets_for_sel_ldr; |
| 113 std::vector<nacl::FileDescriptor> handles_for_renderer; | |
| 113 }; | 114 }; |
| 114 | 115 |
| 115 // ----------------------------------------------------------------------------- | 116 // ----------------------------------------------------------------------------- |
| 116 | 117 |
| 117 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, bool off_the_record) | 118 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, bool off_the_record) |
| 118 : manifest_url_(manifest_url), | 119 : manifest_url_(manifest_url), |
| 119 #if defined(OS_WIN) | 120 #if defined(OS_WIN) |
| 120 process_launched_by_broker_(false), | 121 process_launched_by_broker_(false), |
| 121 #elif defined(OS_LINUX) | 122 #elif defined(OS_LINUX) |
| 122 wait_for_nacl_gdb_(false), | 123 wait_for_nacl_gdb_(false), |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 530 bool handled = true; | 531 bool handled = true; |
| 531 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | 532 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) |
| 532 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, | 533 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, |
| 533 OnQueryKnownToValidate) | 534 OnQueryKnownToValidate) |
| 534 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, | 535 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, |
| 535 OnSetKnownToValidate) | 536 OnSetKnownToValidate) |
| 536 #if defined(OS_WIN) | 537 #if defined(OS_WIN) |
| 537 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, | 538 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, |
| 538 OnAttachDebugExceptionHandler) | 539 OnAttachDebugExceptionHandler) |
| 539 #endif | 540 #endif |
| 541 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated, | |
| 542 OnPpapiChannelCreated) | |
| 540 IPC_MESSAGE_UNHANDLED(handled = false) | 543 IPC_MESSAGE_UNHANDLED(handled = false) |
| 541 IPC_END_MESSAGE_MAP() | 544 IPC_END_MESSAGE_MAP() |
| 542 return handled; | 545 return handled; |
| 543 } | 546 } |
| 544 | 547 |
| 545 void NaClProcessHost::OnProcessLaunched() { | 548 void NaClProcessHost::OnProcessLaunched() { |
| 546 if (!StartWithLaunchedProcess()) | 549 if (!StartWithLaunchedProcess()) |
| 547 delete this; | 550 delete this; |
| 548 } | 551 } |
| 549 | 552 |
| 550 // Called when the NaClBrowser singleton has been fully initialized. | 553 // Called when the NaClBrowser singleton has been fully initialized. |
| 551 void NaClProcessHost::OnResourcesReady() { | 554 void NaClProcessHost::OnResourcesReady() { |
| 552 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 555 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 553 if (!nacl_browser->IsReady() || !SendStart()) { | 556 if (!nacl_browser->IsReady() || !SendStart()) { |
| 554 DLOG(ERROR) << "Cannot launch NaCl process"; | 557 DLOG(ERROR) << "Cannot launch NaCl process"; |
| 555 delete this; | 558 delete this; |
| 556 } | 559 } |
| 557 } | 560 } |
| 558 | 561 |
| 559 bool NaClProcessHost::ReplyToRenderer() { | 562 bool NaClProcessHost::SendStart() { |
|
Mark Seaborn
2012/06/20 19:24:40
Why do you need to merge ReplyToRenderer() and Sta
bbudge
2012/06/21 00:00:46
I merged these because we now have to wait for the
Mark Seaborn
2012/06/21 15:30:03
I understand why you've done it, but I don't think
bbudge
2012/06/21 18:16:53
Done. Good idea, it's a much smaller change this w
| |
| 560 std::vector<nacl::FileDescriptor> handles_for_renderer; | |
| 561 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { | 563 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
| 562 #if defined(OS_WIN) | 564 #if defined(OS_WIN) |
| 563 // Copy the handle into the renderer process. | 565 // Copy the handle into the renderer process. |
| 564 HANDLE handle_in_renderer; | 566 HANDLE handle_in_renderer; |
| 565 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 567 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
| 566 reinterpret_cast<HANDLE>( | 568 reinterpret_cast<HANDLE>( |
| 567 internal_->sockets_for_renderer[i]), | 569 internal_->sockets_for_renderer[i]), |
| 568 chrome_render_message_filter_->peer_handle(), | 570 chrome_render_message_filter_->peer_handle(), |
| 569 &handle_in_renderer, | 571 &handle_in_renderer, |
| 570 0, // Unused given DUPLICATE_SAME_ACCESS. | 572 0, // Unused given DUPLICATE_SAME_ACCESS. |
| 571 FALSE, | 573 FALSE, |
| 572 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 574 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
| 573 DLOG(ERROR) << "DuplicateHandle() failed"; | 575 DLOG(ERROR) << "DuplicateHandle() failed"; |
| 574 return false; | 576 return false; |
| 575 } | 577 } |
| 576 handles_for_renderer.push_back( | 578 internal_->handles_for_renderer.push_back( |
| 577 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); | 579 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); |
| 578 #else | 580 #else |
| 579 // No need to dup the imc_handle - we don't pass it anywhere else so | 581 // No need to dup the imc_handle - we don't pass it anywhere else so |
| 580 // it cannot be closed. | 582 // it cannot be closed. |
| 581 nacl::FileDescriptor imc_handle; | 583 nacl::FileDescriptor imc_handle; |
| 582 imc_handle.fd = internal_->sockets_for_renderer[i]; | 584 imc_handle.fd = internal_->sockets_for_renderer[i]; |
| 583 imc_handle.auto_close = true; | 585 imc_handle.auto_close = true; |
| 584 handles_for_renderer.push_back(imc_handle); | 586 internal_->handles_for_renderer.push_back(imc_handle); |
| 585 #endif | 587 #endif |
| 586 } | 588 } |
| 587 | 589 |
| 590 const ChildProcessData& data = process_->GetData(); | |
| 588 #if defined(OS_WIN) | 591 #if defined(OS_WIN) |
| 589 // If we are on 64-bit Windows, the NaCl process's sandbox is | 592 // If we are on 64-bit Windows, the NaCl process's sandbox is |
| 590 // managed by a different process from the renderer's sandbox. We | 593 // managed by a different process from the renderer's sandbox. We |
| 591 // need to inform the renderer's sandbox about the NaCl process so | 594 // need to inform the renderer's sandbox about the NaCl process so |
| 592 // that the renderer can send handles to the NaCl process using | 595 // that the renderer can send handles to the NaCl process using |
| 593 // BrokerDuplicateHandle(). | 596 // BrokerDuplicateHandle(). |
| 594 if (RunningOnWOW64()) { | 597 if (RunningOnWOW64()) { |
| 595 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { | 598 if (!content::BrokerAddTargetPeer(data.handle)) { |
| 596 DLOG(ERROR) << "Failed to add NaCl process PID"; | 599 DLOG(ERROR) << "Failed to add NaCl process PID"; |
| 597 return false; | 600 return false; |
| 598 } | 601 } |
| 599 } | 602 } |
| 600 #endif | 603 #endif |
| 601 | 604 |
| 602 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | |
| 603 reply_msg_, handles_for_renderer); | |
| 604 chrome_render_message_filter_->Send(reply_msg_); | |
| 605 chrome_render_message_filter_ = NULL; | |
| 606 reply_msg_ = NULL; | |
| 607 internal_->sockets_for_renderer.clear(); | |
|
Mark Seaborn
2012/06/20 19:24:40
Removing this call isn't quite right. If NaClProc
bbudge
2012/06/21 00:00:46
I'm adding a TODO to fix this. I think we should c
| |
| 608 return true; | |
| 609 } | |
| 610 | |
| 611 bool NaClProcessHost::StartNaClExecution() { | |
| 612 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 605 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 613 | 606 |
| 614 nacl::NaClStartParams params; | 607 nacl::NaClStartParams params; |
| 615 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); | 608 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); |
| 616 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); | 609 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); |
| 617 params.version = chrome::VersionInfo().CreateVersionString(); | 610 params.version = chrome::VersionInfo().CreateVersionString(); |
| 618 params.enable_exception_handling = enable_exception_handling_; | 611 params.enable_exception_handling = enable_exception_handling_; |
| 619 params.enable_debug_stub = | 612 params.enable_debug_stub = |
| 620 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaClDebug); | 613 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaClDebug); |
| 614 params.enable_ipc_proxy = CommandLine::ForCurrentProcess()->HasSwitch( | |
| 615 switches::kEnableNaClIPCProxy); | |
| 621 | 616 |
| 622 base::PlatformFile irt_file = nacl_browser->IrtFile(); | 617 base::PlatformFile irt_file = nacl_browser->IrtFile(); |
| 623 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); | 618 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); |
| 624 | 619 |
| 625 const ChildProcessData& data = process_->GetData(); | |
| 626 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { | 620 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
| 627 if (!ShareHandleToSelLdr(data.handle, | 621 if (!ShareHandleToSelLdr(data.handle, |
| 628 internal_->sockets_for_sel_ldr[i], true, | 622 internal_->sockets_for_sel_ldr[i], true, |
| 629 ¶ms.handles)) { | 623 ¶ms.handles)) { |
| 630 return false; | 624 return false; |
| 631 } | 625 } |
| 632 } | 626 } |
| 633 | 627 |
| 634 // Send over the IRT file handle. We don't close our own copy! | 628 // Send over the IRT file handle. We don't close our own copy! |
| 635 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) | 629 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 651 nacl::FileDescriptor memory_fd; | 645 nacl::FileDescriptor memory_fd; |
| 652 memory_fd.fd = dup(memory_buffer.handle().fd); | 646 memory_fd.fd = dup(memory_buffer.handle().fd); |
| 653 if (memory_fd.fd < 0) { | 647 if (memory_fd.fd < 0) { |
| 654 DLOG(ERROR) << "Failed to dup() a file descriptor"; | 648 DLOG(ERROR) << "Failed to dup() a file descriptor"; |
| 655 return false; | 649 return false; |
| 656 } | 650 } |
| 657 memory_fd.auto_close = true; | 651 memory_fd.auto_close = true; |
| 658 params.handles.push_back(memory_fd); | 652 params.handles.push_back(memory_fd); |
| 659 #endif | 653 #endif |
| 660 | 654 |
| 655 // The start message should only be sent once we are sure we won't delete | |
| 656 // ourselves. | |
| 661 process_->Send(new NaClProcessMsg_Start(params)); | 657 process_->Send(new NaClProcessMsg_Start(params)); |
| 662 | 658 |
| 663 internal_->sockets_for_sel_ldr.clear(); | 659 internal_->sockets_for_sel_ldr.clear(); |
| 660 | |
| 661 // If we aren't creating the IPC channel, send the reply message without | |
| 662 // waiting for the NaCl process to signal that it's ready. | |
| 663 // TODO(bbudge) remove this after we switch to the IPC proxy. | |
| 664 if (!params.enable_ipc_proxy) { | |
| 665 OnPpapiChannelCreated(IPC::ChannelHandle()); | |
| 666 } | |
| 667 | |
| 664 return true; | 668 return true; |
| 665 } | 669 } |
| 666 | 670 |
| 667 bool NaClProcessHost::SendStart() { | 671 void NaClProcessHost::OnPpapiChannelCreated( |
| 668 return ReplyToRenderer() && StartNaClExecution(); | 672 const IPC::ChannelHandle& channel_handle) { |
| 673 // Now that the server end of the channel has been created, send the reply to | |
| 674 // the renderer. | |
| 675 base::ProcessId nacl_process_id = base::GetProcId(process_->GetData().handle); | |
| 676 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | |
| 677 reply_msg_, internal_->handles_for_renderer, channel_handle, | |
| 678 nacl_process_id); | |
| 679 chrome_render_message_filter_->Send(reply_msg_); | |
| 680 chrome_render_message_filter_ = NULL; | |
| 681 reply_msg_ = NULL; | |
| 682 | |
| 683 internal_->sockets_for_renderer.clear(); | |
| 684 internal_->handles_for_renderer.clear(); | |
| 669 } | 685 } |
| 670 | 686 |
| 671 bool NaClProcessHost::StartWithLaunchedProcess() { | 687 bool NaClProcessHost::StartWithLaunchedProcess() { |
| 672 #if defined(OS_LINUX) | 688 #if defined(OS_LINUX) |
| 673 if (wait_for_nacl_gdb_) { | 689 if (wait_for_nacl_gdb_) { |
| 674 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { | 690 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { |
| 675 // We will be called with wait_for_nacl_gdb_ = false once debugger is | 691 // We will be called with wait_for_nacl_gdb_ = false once debugger is |
| 676 // attached to the program. | 692 // attached to the program. |
| 677 return true; | 693 return true; |
| 678 } | 694 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 } else { | 781 } else { |
| 766 NaClStartDebugExceptionHandlerThread( | 782 NaClStartDebugExceptionHandlerThread( |
| 767 process_handle.Take(), info, | 783 process_handle.Take(), info, |
| 768 base::MessageLoopProxy::current(), | 784 base::MessageLoopProxy::current(), |
| 769 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 785 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 770 weak_factory_.GetWeakPtr())); | 786 weak_factory_.GetWeakPtr())); |
| 771 return true; | 787 return true; |
| 772 } | 788 } |
| 773 } | 789 } |
| 774 #endif | 790 #endif |
| OLD | NEW |