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

Side by Side Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 10214007: Add an IPC channel between the NaCl loader process and the renderer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 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 #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
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
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() {
560 std::vector<nacl::FileDescriptor> handles_for_renderer; 563 const ChildProcessData& data = process_->GetData();
561 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
562 #if defined(OS_WIN)
563 // Copy the handle into the renderer process.
564 HANDLE handle_in_renderer;
565 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
566 reinterpret_cast<HANDLE>(
567 internal_->sockets_for_renderer[i]),
568 chrome_render_message_filter_->peer_handle(),
569 &handle_in_renderer,
570 0, // Unused given DUPLICATE_SAME_ACCESS.
571 FALSE,
572 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
573 DLOG(ERROR) << "DuplicateHandle() failed";
574 return false;
575 }
576 handles_for_renderer.push_back(
577 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer));
578 #else
579 // No need to dup the imc_handle - we don't pass it anywhere else so
580 // it cannot be closed.
581 nacl::FileDescriptor imc_handle;
582 imc_handle.fd = internal_->sockets_for_renderer[i];
583 imc_handle.auto_close = true;
584 handles_for_renderer.push_back(imc_handle);
585 #endif
586 }
587
588 #if defined(OS_WIN) 564 #if defined(OS_WIN)
589 // If we are on 64-bit Windows, the NaCl process's sandbox is 565 // 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 566 // managed by a different process from the renderer's sandbox. We
591 // need to inform the renderer's sandbox about the NaCl process so 567 // need to inform the renderer's sandbox about the NaCl process so
592 // that the renderer can send handles to the NaCl process using 568 // that the renderer can send handles to the NaCl process using
593 // BrokerDuplicateHandle(). 569 // BrokerDuplicateHandle().
594 if (RunningOnWOW64()) { 570 if (RunningOnWOW64()) {
595 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { 571 if (!content::BrokerAddTargetPeer(data.handle)) {
596 DLOG(ERROR) << "Failed to add NaCl process PID"; 572 DLOG(ERROR) << "Failed to add NaCl process PID";
597 return false; 573 return false;
598 } 574 }
599 } 575 }
600 #endif 576 #endif
601 577
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();
608 return true;
609 }
610
611 bool NaClProcessHost::StartNaClExecution() {
612 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 578 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
613 579
614 nacl::NaClStartParams params; 580 nacl::NaClStartParams params;
615 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); 581 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled();
616 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); 582 params.validation_cache_key = nacl_browser->GetValidationCacheKey();
617 params.version = chrome::VersionInfo().CreateVersionString(); 583 params.version = chrome::VersionInfo().CreateVersionString();
618 params.enable_exception_handling = enable_exception_handling_; 584 params.enable_exception_handling = enable_exception_handling_;
619 params.enable_debug_stub = 585 params.enable_debug_stub =
620 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaClDebug); 586 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaClDebug);
587 params.enable_ipc_proxy = CommandLine::ForCurrentProcess()->HasSwitch(
588 switches::kEnableNaClIPCProxy);
621 589
622 base::PlatformFile irt_file = nacl_browser->IrtFile(); 590 base::PlatformFile irt_file = nacl_browser->IrtFile();
623 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); 591 CHECK_NE(irt_file, base::kInvalidPlatformFileValue);
624 592
625 const ChildProcessData& data = process_->GetData(); 593 // TODO(bbudge) In case of errors, the destructor may close handles that
594 // have already been closed by DuplicateHandle, which is unsafe. Add some
595 // helper functions that can be invoked when handle duplication fails, to
596 // clean more carefully.
626 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { 597 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
627 if (!ShareHandleToSelLdr(data.handle, 598 if (!ShareHandleToSelLdr(data.handle,
628 internal_->sockets_for_sel_ldr[i], true, 599 internal_->sockets_for_sel_ldr[i], true,
629 &params.handles)) { 600 &params.handles)) {
630 return false; 601 return false;
631 } 602 }
632 } 603 }
633 604
634 // Send over the IRT file handle. We don't close our own copy! 605 // Send over the IRT file handle. We don't close our own copy!
635 if (!ShareHandleToSelLdr(data.handle, irt_file, false, &params.handles)) 606 if (!ShareHandleToSelLdr(data.handle, irt_file, false, &params.handles))
(...skipping 15 matching lines...) Expand all
651 nacl::FileDescriptor memory_fd; 622 nacl::FileDescriptor memory_fd;
652 memory_fd.fd = dup(memory_buffer.handle().fd); 623 memory_fd.fd = dup(memory_buffer.handle().fd);
653 if (memory_fd.fd < 0) { 624 if (memory_fd.fd < 0) {
654 DLOG(ERROR) << "Failed to dup() a file descriptor"; 625 DLOG(ERROR) << "Failed to dup() a file descriptor";
655 return false; 626 return false;
656 } 627 }
657 memory_fd.auto_close = true; 628 memory_fd.auto_close = true;
658 params.handles.push_back(memory_fd); 629 params.handles.push_back(memory_fd);
659 #endif 630 #endif
660 631
632 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
633 #if defined(OS_WIN)
634 // Copy the handle into the renderer process.
635 HANDLE handle_in_renderer;
636 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
637 reinterpret_cast<HANDLE>(
638 internal_->sockets_for_renderer[i]),
639 chrome_render_message_filter_->peer_handle(),
640 &handle_in_renderer,
641 0, // Unused given DUPLICATE_SAME_ACCESS.
642 FALSE,
643 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
644 DLOG(ERROR) << "DuplicateHandle() failed";
645 return false;
646 }
647 internal_->handles_for_renderer.push_back(
648 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer));
649 #else
650 // No need to dup the imc_handle - we don't pass it anywhere else so
651 // it cannot be closed.
652 nacl::FileDescriptor imc_handle;
653 imc_handle.fd = internal_->sockets_for_renderer[i];
654 imc_handle.auto_close = true;
655 internal_->handles_for_renderer.push_back(imc_handle);
656 #endif
657 }
658
659 // The start message should only be sent once we are sure we won't delete
660 // ourselves.
661 process_->Send(new NaClProcessMsg_Start(params)); 661 process_->Send(new NaClProcessMsg_Start(params));
662 662
663 internal_->sockets_for_sel_ldr.clear(); 663 internal_->sockets_for_sel_ldr.clear();
664
665 // If we aren't creating the IPC channel, send the reply message without
666 // waiting for the NaCl process to signal that it's ready.
667 // TODO(bbudge) remove this after we switch to the IPC proxy.
668 if (!params.enable_ipc_proxy) {
669 OnPpapiChannelCreated(IPC::ChannelHandle());
670 }
671
664 return true; 672 return true;
665 } 673 }
666 674
667 bool NaClProcessHost::SendStart() { 675 void NaClProcessHost::OnPpapiChannelCreated(
668 return ReplyToRenderer() && StartNaClExecution(); 676 const IPC::ChannelHandle& channel_handle) {
677 // Now that the server end of the channel has been created, send the reply to
678 // the renderer.
679 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
680 reply_msg_, internal_->handles_for_renderer, channel_handle);
681 chrome_render_message_filter_->Send(reply_msg_);
682 chrome_render_message_filter_ = NULL;
683 reply_msg_ = NULL;
684
685 internal_->sockets_for_renderer.clear();
686 internal_->handles_for_renderer.clear();
669 } 687 }
670 688
671 bool NaClProcessHost::StartWithLaunchedProcess() { 689 bool NaClProcessHost::StartWithLaunchedProcess() {
672 #if defined(OS_LINUX) 690 #if defined(OS_LINUX)
673 if (wait_for_nacl_gdb_) { 691 if (wait_for_nacl_gdb_) {
674 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { 692 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) {
675 // We will be called with wait_for_nacl_gdb_ = false once debugger is 693 // We will be called with wait_for_nacl_gdb_ = false once debugger is
676 // attached to the program. 694 // attached to the program.
677 return true; 695 return true;
678 } 696 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 } else { 783 } else {
766 NaClStartDebugExceptionHandlerThread( 784 NaClStartDebugExceptionHandlerThread(
767 process_handle.Take(), info, 785 process_handle.Take(), info,
768 base::MessageLoopProxy::current(), 786 base::MessageLoopProxy::current(),
769 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 787 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
770 weak_factory_.GetWeakPtr())); 788 weak_factory_.GetWeakPtr()));
771 return true; 789 return true;
772 } 790 }
773 } 791 }
774 #endif 792 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698