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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 << irt_filepath_.LossyDisplayName() | 294 << irt_filepath_.LossyDisplayName() |
295 << "\": " << error_code; | 295 << "\": " << error_code; |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 } // namespace | 299 } // namespace |
300 | 300 |
301 struct NaClProcessHost::NaClInternal { | 301 struct NaClProcessHost::NaClInternal { |
302 std::vector<nacl::Handle> sockets_for_renderer; | 302 std::vector<nacl::Handle> sockets_for_renderer; |
303 std::vector<nacl::Handle> sockets_for_sel_ldr; | 303 std::vector<nacl::Handle> sockets_for_sel_ldr; |
| 304 std::vector<nacl::FileDescriptor> handles_for_renderer; |
304 }; | 305 }; |
305 | 306 |
306 // ----------------------------------------------------------------------------- | 307 // ----------------------------------------------------------------------------- |
307 | 308 |
308 NaClProcessHost::NaClProcessHost(const GURL& manifest_url) | 309 NaClProcessHost::NaClProcessHost(const GURL& manifest_url) |
309 : manifest_url_(manifest_url), | 310 : manifest_url_(manifest_url), |
310 #if defined(OS_WIN) | 311 #if defined(OS_WIN) |
311 process_launched_by_broker_(false), | 312 process_launched_by_broker_(false), |
312 #elif defined(OS_LINUX) | 313 #elif defined(OS_LINUX) |
313 wait_for_nacl_gdb_(false), | 314 wait_for_nacl_gdb_(false), |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 bool handled = true; | 707 bool handled = true; |
707 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | 708 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) |
708 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, | 709 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, |
709 OnQueryKnownToValidate) | 710 OnQueryKnownToValidate) |
710 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, | 711 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, |
711 OnSetKnownToValidate) | 712 OnSetKnownToValidate) |
712 #if defined(OS_WIN) | 713 #if defined(OS_WIN) |
713 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, | 714 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, |
714 OnAttachDebugExceptionHandler) | 715 OnAttachDebugExceptionHandler) |
715 #endif | 716 #endif |
| 717 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated, |
| 718 OnPpapiChannelCreated) |
716 IPC_MESSAGE_UNHANDLED(handled = false) | 719 IPC_MESSAGE_UNHANDLED(handled = false) |
717 IPC_END_MESSAGE_MAP() | 720 IPC_END_MESSAGE_MAP() |
718 return handled; | 721 return handled; |
719 } | 722 } |
720 | 723 |
721 void NaClProcessHost::OnProcessCrashed(int exit_code) { | 724 void NaClProcessHost::OnProcessCrashed(int exit_code) { |
722 std::string message = base::StringPrintf( | 725 std::string message = base::StringPrintf( |
723 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); | 726 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); |
724 LOG(ERROR) << message; | 727 LOG(ERROR) << message; |
725 } | 728 } |
726 | 729 |
727 void NaClProcessHost::OnProcessLaunched() { | 730 void NaClProcessHost::OnProcessLaunched() { |
728 if (!StartWithLaunchedProcess()) | 731 if (!StartWithLaunchedProcess()) |
729 delete this; | 732 delete this; |
730 } | 733 } |
731 | 734 |
732 // The asynchronous attempt to get the IRT file open has completed. | 735 // The asynchronous attempt to get the IRT file open has completed. |
733 void NaClProcessHost::IrtReady() { | 736 void NaClProcessHost::IrtReady() { |
734 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 737 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
735 if (!nacl_browser->IrtAvailable() || !SendStart()) { | 738 if (!nacl_browser->IrtAvailable() || !SendStart()) { |
736 DLOG(ERROR) << "Cannot launch NaCl process"; | 739 DLOG(ERROR) << "Cannot launch NaCl process"; |
737 delete this; | 740 delete this; |
738 } | 741 } |
739 } | 742 } |
740 | 743 |
741 bool NaClProcessHost::ReplyToRenderer() { | 744 bool NaClProcessHost::SendStart() { |
742 std::vector<nacl::FileDescriptor> handles_for_renderer; | |
743 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { | 745 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
744 #if defined(OS_WIN) | 746 #if defined(OS_WIN) |
745 // Copy the handle into the renderer process. | 747 // Copy the handle into the renderer process. |
746 HANDLE handle_in_renderer; | 748 HANDLE handle_in_renderer; |
747 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 749 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
748 reinterpret_cast<HANDLE>( | 750 reinterpret_cast<HANDLE>( |
749 internal_->sockets_for_renderer[i]), | 751 internal_->sockets_for_renderer[i]), |
750 chrome_render_message_filter_->peer_handle(), | 752 chrome_render_message_filter_->peer_handle(), |
751 &handle_in_renderer, | 753 &handle_in_renderer, |
752 0, // Unused given DUPLICATE_SAME_ACCESS. | 754 0, // Unused given DUPLICATE_SAME_ACCESS. |
753 FALSE, | 755 FALSE, |
754 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 756 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
755 DLOG(ERROR) << "DuplicateHandle() failed"; | 757 DLOG(ERROR) << "DuplicateHandle() failed"; |
756 return false; | 758 return false; |
757 } | 759 } |
758 handles_for_renderer.push_back( | 760 internal_->handles_for_renderer.push_back( |
759 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); | 761 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); |
760 #else | 762 #else |
761 // No need to dup the imc_handle - we don't pass it anywhere else so | 763 // No need to dup the imc_handle - we don't pass it anywhere else so |
762 // it cannot be closed. | 764 // it cannot be closed. |
763 nacl::FileDescriptor imc_handle; | 765 nacl::FileDescriptor imc_handle; |
764 imc_handle.fd = internal_->sockets_for_renderer[i]; | 766 imc_handle.fd = internal_->sockets_for_renderer[i]; |
765 imc_handle.auto_close = true; | 767 imc_handle.auto_close = true; |
766 handles_for_renderer.push_back(imc_handle); | 768 internal_->handles_for_renderer.push_back(imc_handle); |
767 #endif | 769 #endif |
768 } | 770 } |
769 | 771 |
| 772 const ChildProcessData& data = process_->GetData(); |
770 #if defined(OS_WIN) | 773 #if defined(OS_WIN) |
771 // If we are on 64-bit Windows, the NaCl process's sandbox is | 774 // If we are on 64-bit Windows, the NaCl process's sandbox is |
772 // managed by a different process from the renderer's sandbox. We | 775 // managed by a different process from the renderer's sandbox. We |
773 // need to inform the renderer's sandbox about the NaCl process so | 776 // need to inform the renderer's sandbox about the NaCl process so |
774 // that the renderer can send handles to the NaCl process using | 777 // that the renderer can send handles to the NaCl process using |
775 // BrokerDuplicateHandle(). | 778 // BrokerDuplicateHandle(). |
776 if (RunningOnWOW64()) { | 779 if (RunningOnWOW64()) { |
777 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { | 780 if (!content::BrokerAddTargetPeer(data.handle)) { |
778 DLOG(ERROR) << "Failed to add NaCl process PID"; | 781 DLOG(ERROR) << "Failed to add NaCl process PID"; |
779 return false; | 782 return false; |
780 } | 783 } |
781 } | 784 } |
782 #endif | 785 #endif |
783 | 786 |
784 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | |
785 reply_msg_, handles_for_renderer); | |
786 chrome_render_message_filter_->Send(reply_msg_); | |
787 chrome_render_message_filter_ = NULL; | |
788 reply_msg_ = NULL; | |
789 internal_->sockets_for_renderer.clear(); | |
790 return true; | |
791 } | |
792 | |
793 bool NaClProcessHost::StartNaClExecution() { | |
794 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 787 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
795 | 788 |
796 nacl::NaClStartParams params; | 789 nacl::NaClStartParams params; |
797 params.validation_cache_key = nacl_browser->GetValidatorCacheKey(); | 790 params.validation_cache_key = nacl_browser->GetValidatorCacheKey(); |
798 params.version = chrome::VersionInfo().CreateVersionString(); | 791 params.version = chrome::VersionInfo().CreateVersionString(); |
799 params.enable_exception_handling = enable_exception_handling_; | 792 params.enable_exception_handling = enable_exception_handling_; |
800 | 793 |
801 base::PlatformFile irt_file = nacl_browser->IrtFile(); | 794 base::PlatformFile irt_file = nacl_browser->IrtFile(); |
802 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); | 795 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); |
803 | 796 |
804 const ChildProcessData& data = process_->GetData(); | |
805 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { | 797 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
806 if (!ShareHandleToSelLdr(data.handle, | 798 if (!ShareHandleToSelLdr(data.handle, |
807 internal_->sockets_for_sel_ldr[i], true, | 799 internal_->sockets_for_sel_ldr[i], true, |
808 ¶ms.handles)) { | 800 ¶ms.handles)) { |
809 return false; | 801 return false; |
810 } | 802 } |
811 } | 803 } |
812 | 804 |
813 // Send over the IRT file handle. We don't close our own copy! | 805 // Send over the IRT file handle. We don't close our own copy! |
814 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) | 806 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) |
(...skipping 15 matching lines...) Expand all Loading... |
830 nacl::FileDescriptor memory_fd; | 822 nacl::FileDescriptor memory_fd; |
831 memory_fd.fd = dup(memory_buffer.handle().fd); | 823 memory_fd.fd = dup(memory_buffer.handle().fd); |
832 if (memory_fd.fd < 0) { | 824 if (memory_fd.fd < 0) { |
833 DLOG(ERROR) << "Failed to dup() a file descriptor"; | 825 DLOG(ERROR) << "Failed to dup() a file descriptor"; |
834 return false; | 826 return false; |
835 } | 827 } |
836 memory_fd.auto_close = true; | 828 memory_fd.auto_close = true; |
837 params.handles.push_back(memory_fd); | 829 params.handles.push_back(memory_fd); |
838 #endif | 830 #endif |
839 | 831 |
| 832 // The start message should only be sent once we are sure we won't delete |
| 833 // ourselves. |
840 process_->Send(new NaClProcessMsg_Start(params)); | 834 process_->Send(new NaClProcessMsg_Start(params)); |
841 | 835 |
842 internal_->sockets_for_sel_ldr.clear(); | 836 internal_->sockets_for_sel_ldr.clear(); |
843 return true; | 837 return true; |
844 } | 838 } |
845 | 839 |
846 bool NaClProcessHost::SendStart() { | 840 void NaClProcessHost::OnPpapiChannelCreated( |
847 return ReplyToRenderer() && StartNaClExecution(); | 841 const IPC::ChannelHandle& channel_handle) { |
| 842 // Now that the server end of the channel has been created, send the reply to |
| 843 // the renderer. |
| 844 base::ProcessId nacl_process_id = base::GetProcId(process_->GetData().handle); |
| 845 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( |
| 846 reply_msg_, internal_->handles_for_renderer, channel_handle, |
| 847 base::kNullProcessHandle, nacl_process_id); |
| 848 chrome_render_message_filter_->Send(reply_msg_); |
| 849 chrome_render_message_filter_ = NULL; |
| 850 reply_msg_ = NULL; |
| 851 |
| 852 internal_->sockets_for_renderer.clear(); |
| 853 internal_->handles_for_renderer.clear(); |
848 } | 854 } |
849 | 855 |
850 bool NaClProcessHost::StartWithLaunchedProcess() { | 856 bool NaClProcessHost::StartWithLaunchedProcess() { |
851 #if defined(OS_LINUX) | 857 #if defined(OS_LINUX) |
852 if (wait_for_nacl_gdb_) { | 858 if (wait_for_nacl_gdb_) { |
853 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { | 859 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { |
854 // We will be called with wait_for_nacl_gdb_ = false once debugger is | 860 // We will be called with wait_for_nacl_gdb_ = false once debugger is |
855 // attached to the program. | 861 // attached to the program. |
856 return true; | 862 return true; |
857 } | 863 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 } else { | 944 } else { |
939 NaClStartDebugExceptionHandlerThread( | 945 NaClStartDebugExceptionHandlerThread( |
940 process_handle.Take(), | 946 process_handle.Take(), |
941 base::MessageLoopProxy::current(), | 947 base::MessageLoopProxy::current(), |
942 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 948 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
943 weak_factory_.GetWeakPtr())); | 949 weak_factory_.GetWeakPtr())); |
944 return true; | 950 return true; |
945 } | 951 } |
946 } | 952 } |
947 #endif | 953 #endif |
OLD | NEW |