| 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 "components/nacl/browser/nacl_process_host.h" | 5 #include "components/nacl/browser/nacl_process_host.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 #include "content/public/common/content_switches.h" | 41 #include "content/public/common/content_switches.h" |
| 42 #include "content/public/common/process_type.h" | 42 #include "content/public/common/process_type.h" |
| 43 #include "ipc/ipc_channel.h" | 43 #include "ipc/ipc_channel.h" |
| 44 #include "ipc/ipc_switches.h" | 44 #include "ipc/ipc_switches.h" |
| 45 #include "native_client/src/shared/imc/nacl_imc_c.h" | 45 #include "native_client/src/shared/imc/nacl_imc_c.h" |
| 46 #include "net/base/net_util.h" | 46 #include "net/base/net_util.h" |
| 47 #include "net/socket/tcp_listen_socket.h" | 47 #include "net/socket/tcp_listen_socket.h" |
| 48 #include "ppapi/host/host_factory.h" | 48 #include "ppapi/host/host_factory.h" |
| 49 #include "ppapi/host/ppapi_host.h" | 49 #include "ppapi/host/ppapi_host.h" |
| 50 #include "ppapi/proxy/ppapi_messages.h" | 50 #include "ppapi/proxy/ppapi_messages.h" |
| 51 #include "ppapi/shared_impl/ppapi_nacl_channel_args.h" | 51 #include "ppapi/shared_impl/ppapi_initialize_nacl_dispatcher_args.h" |
| 52 #include "ppapi/shared_impl/ppapi_switches.h" | 52 #include "ppapi/shared_impl/ppapi_switches.h" |
| 53 | 53 |
| 54 #if defined(OS_POSIX) | 54 #if defined(OS_POSIX) |
| 55 #include <fcntl.h> | 55 #include <fcntl.h> |
| 56 | 56 |
| 57 #include "ipc/ipc_channel_posix.h" | 57 #include "ipc/ipc_channel_posix.h" |
| 58 #elif defined(OS_WIN) | 58 #elif defined(OS_WIN) |
| 59 #include <windows.h> | 59 #include <windows.h> |
| 60 | 60 |
| 61 #include "base/threading/thread.h" | 61 #include "base/threading/thread.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 NaClHandle socket_for_renderer; | 210 NaClHandle socket_for_renderer; |
| 211 NaClHandle socket_for_sel_ldr; | 211 NaClHandle socket_for_sel_ldr; |
| 212 | 212 |
| 213 NaClInternal() | 213 NaClInternal() |
| 214 : socket_for_renderer(NACL_INVALID_HANDLE), | 214 : socket_for_renderer(NACL_INVALID_HANDLE), |
| 215 socket_for_sel_ldr(NACL_INVALID_HANDLE) { } | 215 socket_for_sel_ldr(NACL_INVALID_HANDLE) { } |
| 216 }; | 216 }; |
| 217 | 217 |
| 218 // ----------------------------------------------------------------------------- | 218 // ----------------------------------------------------------------------------- |
| 219 | 219 |
| 220 NaClProcessHost::PluginListener::PluginListener(NaClProcessHost* host) | |
| 221 : host_(host) { | |
| 222 } | |
| 223 | |
| 224 bool NaClProcessHost::PluginListener::OnMessageReceived( | |
| 225 const IPC::Message& msg) { | |
| 226 return host_->OnUntrustedMessageForwarded(msg); | |
| 227 } | |
| 228 | |
| 229 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, | 220 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, |
| 230 int render_view_id, | 221 int render_view_id, |
| 231 uint32 permission_bits, | 222 uint32 permission_bits, |
| 232 bool uses_irt, | 223 bool uses_irt, |
| 233 bool enable_dyncode_syscalls, | 224 bool enable_dyncode_syscalls, |
| 234 bool enable_exception_handling, | 225 bool enable_exception_handling, |
| 235 bool enable_crash_throttling, | 226 bool enable_crash_throttling, |
| 236 bool off_the_record, | 227 bool off_the_record, |
| 237 const base::FilePath& profile_directory) | 228 const base::FilePath& profile_directory) |
| 238 : manifest_url_(manifest_url), | 229 : manifest_url_(manifest_url), |
| 239 permissions_(GetNaClPermissions(permission_bits)), | 230 permissions_(GetNaClPermissions(permission_bits)), |
| 240 #if defined(OS_WIN) | 231 #if defined(OS_WIN) |
| 241 process_launched_by_broker_(false), | 232 process_launched_by_broker_(false), |
| 242 #endif | 233 #endif |
| 243 reply_msg_(NULL), | 234 reply_msg_(NULL), |
| 244 #if defined(OS_WIN) | 235 #if defined(OS_WIN) |
| 245 debug_exception_handler_requested_(false), | 236 debug_exception_handler_requested_(false), |
| 246 #endif | 237 #endif |
| 247 internal_(new NaClInternal()), | 238 internal_(new NaClInternal()), |
| 248 weak_factory_(this), | 239 weak_factory_(this), |
| 249 uses_irt_(uses_irt), | 240 uses_irt_(uses_irt), |
| 250 enable_debug_stub_(false), | 241 enable_debug_stub_(false), |
| 251 enable_dyncode_syscalls_(enable_dyncode_syscalls), | 242 enable_dyncode_syscalls_(enable_dyncode_syscalls), |
| 252 enable_exception_handling_(enable_exception_handling), | 243 enable_exception_handling_(enable_exception_handling), |
| 253 enable_crash_throttling_(enable_crash_throttling), | 244 enable_crash_throttling_(enable_crash_throttling), |
| 254 off_the_record_(off_the_record), | 245 off_the_record_(off_the_record), |
| 255 profile_directory_(profile_directory), | 246 profile_directory_(profile_directory), |
| 256 ipc_plugin_listener_(this), | |
| 257 render_view_id_(render_view_id) { | 247 render_view_id_(render_view_id) { |
| 258 process_.reset(content::BrowserChildProcessHost::Create( | 248 process_.reset(content::BrowserChildProcessHost::Create( |
| 259 PROCESS_TYPE_NACL_LOADER, this)); | 249 PROCESS_TYPE_NACL_LOADER, this)); |
| 260 | 250 |
| 261 // Set the display name so the user knows what plugin the process is running. | 251 // Set the display name so the user knows what plugin the process is running. |
| 262 // We aren't on the UI thread so getting the pref locale for language | 252 // We aren't on the UI thread so getting the pref locale for language |
| 263 // formatting isn't possible, so IDN will be lost, but this is probably OK | 253 // formatting isn't possible, so IDN will be lost, but this is probably OK |
| 264 // for this use case. | 254 // for this use case. |
| 265 process_->SetName(net::FormatUrl(manifest_url_, std::string())); | 255 process_->SetName(net::FormatUrl(manifest_url_, std::string())); |
| 266 | 256 |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, | 554 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, |
| 565 OnQueryKnownToValidate) | 555 OnQueryKnownToValidate) |
| 566 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, | 556 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, |
| 567 OnSetKnownToValidate) | 557 OnSetKnownToValidate) |
| 568 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken, | 558 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_ResolveFileToken, |
| 569 OnResolveFileToken) | 559 OnResolveFileToken) |
| 570 #if defined(OS_WIN) | 560 #if defined(OS_WIN) |
| 571 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, | 561 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, |
| 572 OnAttachDebugExceptionHandler) | 562 OnAttachDebugExceptionHandler) |
| 573 #endif | 563 #endif |
| 574 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated, | 564 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, |
| 575 OnPpapiBrowserChannelCreated) | 565 OnPpapiChannelsCreated) |
| 576 IPC_MESSAGE_UNHANDLED(handled = false) | 566 IPC_MESSAGE_UNHANDLED(handled = false) |
| 577 IPC_END_MESSAGE_MAP() | 567 IPC_END_MESSAGE_MAP() |
| 578 return handled; | 568 return handled; |
| 579 } | 569 } |
| 580 | 570 |
| 581 void NaClProcessHost::OnProcessLaunched() { | 571 void NaClProcessHost::OnProcessLaunched() { |
| 582 if (!StartWithLaunchedProcess()) | 572 if (!StartWithLaunchedProcess()) |
| 583 delete this; | 573 delete this; |
| 584 } | 574 } |
| 585 | 575 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 bool NaClProcessHost::SendStart() { | 769 bool NaClProcessHost::SendStart() { |
| 780 if (!enable_ppapi_proxy()) { | 770 if (!enable_ppapi_proxy()) { |
| 781 if (!ReplyToRenderer(IPC::ChannelHandle())) | 771 if (!ReplyToRenderer(IPC::ChannelHandle())) |
| 782 return false; | 772 return false; |
| 783 } | 773 } |
| 784 return StartNaClExecution(); | 774 return StartNaClExecution(); |
| 785 } | 775 } |
| 786 | 776 |
| 787 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is | 777 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is |
| 788 // received. | 778 // received. |
| 789 void NaClProcessHost::OnPpapiBrowserChannelCreated( | 779 void NaClProcessHost::OnPpapiChannelsCreated( |
| 790 const IPC::ChannelHandle& channel_handle) { | 780 const IPC::ChannelHandle& browser_channel_handle, |
| 781 const IPC::ChannelHandle& renderer_channel_handle) { |
| 791 // Only renderer processes should create a channel. | 782 // Only renderer processes should create a channel. |
| 792 DCHECK(enable_ppapi_proxy()); | 783 DCHECK(enable_ppapi_proxy()); |
| 793 if (!ipc_proxy_channel_.get()) { | 784 if (!ipc_proxy_channel_.get()) { |
| 794 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); | 785 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); |
| 795 | 786 |
| 796 ipc_proxy_channel_.reset( | 787 ipc_proxy_channel_.reset( |
| 797 new IPC::ChannelProxy(channel_handle, | 788 new IPC::ChannelProxy(browser_channel_handle, |
| 798 IPC::Channel::MODE_CLIENT, | 789 IPC::Channel::MODE_CLIENT, |
| 799 &ipc_plugin_listener_, | 790 NULL, |
| 800 base::MessageLoopProxy::current().get())); | 791 base::MessageLoopProxy::current().get())); |
| 801 // Create the browser ppapi host and enable PPAPI message dispatching to the | 792 // Create the browser ppapi host and enable PPAPI message dispatching to the |
| 802 // browser process. | 793 // browser process. |
| 803 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( | 794 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( |
| 804 ipc_proxy_channel_.get(), // sender | 795 ipc_proxy_channel_.get(), // sender |
| 805 permissions_, | 796 permissions_, |
| 806 process_->GetData().handle, | 797 process_->GetData().handle, |
| 807 ipc_proxy_channel_.get(), | 798 ipc_proxy_channel_.get(), |
| 808 nacl_host_message_filter_->render_process_id(), | 799 nacl_host_message_filter_->render_process_id(), |
| 809 render_view_id_, | 800 render_view_id_, |
| 810 profile_directory_)); | 801 profile_directory_)); |
| 811 ppapi_host_->SetOnKeepaliveCallback( | 802 ppapi_host_->SetOnKeepaliveCallback( |
| 812 NaClBrowser::GetDelegate()->GetOnKeepaliveCallback()); | 803 NaClBrowser::GetDelegate()->GetOnKeepaliveCallback()); |
| 813 | 804 |
| 814 ppapi::PpapiNaClChannelArgs args; | 805 ppapi::PpapiInitializeNaClDispatcherArgs args; |
| 815 args.off_the_record = nacl_host_message_filter_->off_the_record(); | 806 args.off_the_record = nacl_host_message_filter_->off_the_record(); |
| 816 args.permissions = permissions_; | 807 args.permissions = permissions_; |
| 817 CommandLine* cmdline = CommandLine::ForCurrentProcess(); | 808 CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
| 818 DCHECK(cmdline); | 809 DCHECK(cmdline); |
| 819 std::string flag_whitelist[] = { | 810 std::string flag_whitelist[] = { |
| 820 switches::kPpapiKeepAliveThrottle, | 811 switches::kPpapiKeepAliveThrottle, |
| 821 switches::kV, | 812 switches::kV, |
| 822 switches::kVModule, | 813 switches::kVModule, |
| 823 }; | 814 }; |
| 824 for (size_t i = 0; i < arraysize(flag_whitelist); ++i) { | 815 for (size_t i = 0; i < arraysize(flag_whitelist); ++i) { |
| 825 std::string value = cmdline->GetSwitchValueASCII(flag_whitelist[i]); | 816 std::string value = cmdline->GetSwitchValueASCII(flag_whitelist[i]); |
| 826 if (!value.empty()) { | 817 if (!value.empty()) { |
| 827 args.switch_names.push_back(flag_whitelist[i]); | 818 args.switch_names.push_back(flag_whitelist[i]); |
| 828 args.switch_values.push_back(value); | 819 args.switch_values.push_back(value); |
| 829 } | 820 } |
| 830 } | 821 } |
| 831 | 822 |
| 832 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( | 823 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( |
| 833 scoped_ptr<ppapi::host::HostFactory>( | 824 scoped_ptr<ppapi::host::HostFactory>( |
| 834 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( | 825 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( |
| 835 ppapi_host_.get()))); | 826 ppapi_host_.get()))); |
| 836 | 827 |
| 837 // Send a message to create the NaCl-Renderer channel. The handle is just | 828 // Send a message to initialize the IPC dispatchers in the NaCl plugin. |
| 838 // a place holder. | 829 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); |
| 839 ipc_proxy_channel_->Send( | 830 |
| 840 new PpapiMsg_CreateNaClChannel( | 831 // Let the renderer know that the IPC channels are established. |
| 841 args, | 832 ReplyToRenderer(renderer_channel_handle); |
| 842 SerializedHandle(SerializedHandle::CHANNEL_HANDLE, | |
| 843 IPC::InvalidPlatformFileForTransit()))); | |
| 844 } else { | 833 } else { |
| 845 // Attempt to open more than 1 browser channel is not supported. | 834 // Attempt to open more than 1 browser channel is not supported. |
| 846 // Shut down the NaCl process. | 835 // Shut down the NaCl process. |
| 847 process_->GetHost()->ForceShutdown(); | 836 process_->GetHost()->ForceShutdown(); |
| 848 } | 837 } |
| 849 } | 838 } |
| 850 | 839 |
| 851 void NaClProcessHost::OnPpapiRendererChannelCreated( | |
| 852 const IPC::ChannelHandle& channel_handle) { | |
| 853 if (reply_msg_) { | |
| 854 ReplyToRenderer(channel_handle); | |
| 855 } else { | |
| 856 // Attempt to open more than 1 NaCl renderer channel is not supported. | |
| 857 // Shut down the NaCl process. | |
| 858 process_->GetHost()->ForceShutdown(); | |
| 859 } | |
| 860 } | |
| 861 | |
| 862 bool NaClProcessHost::OnUntrustedMessageForwarded(const IPC::Message& msg) { | |
| 863 // Handle messages that have been forwarded from our PluginListener. | |
| 864 // These messages come from untrusted code so should be handled with care. | |
| 865 bool handled = true; | |
| 866 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | |
| 867 IPC_MESSAGE_HANDLER(PpapiHostMsg_NaClChannelCreated, | |
| 868 OnPpapiRendererChannelCreated) | |
| 869 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 870 IPC_END_MESSAGE_MAP() | |
| 871 return handled; | |
| 872 } | |
| 873 | |
| 874 bool NaClProcessHost::StartWithLaunchedProcess() { | 840 bool NaClProcessHost::StartWithLaunchedProcess() { |
| 875 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 841 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 876 | 842 |
| 877 if (nacl_browser->IsReady()) { | 843 if (nacl_browser->IsReady()) { |
| 878 return SendStart(); | 844 return SendStart(); |
| 879 } else if (nacl_browser->IsOk()) { | 845 } else if (nacl_browser->IsOk()) { |
| 880 nacl_browser->WaitForResources( | 846 nacl_browser->WaitForResources( |
| 881 base::Bind(&NaClProcessHost::OnResourcesReady, | 847 base::Bind(&NaClProcessHost::OnResourcesReady, |
| 882 weak_factory_.GetWeakPtr())); | 848 weak_factory_.GetWeakPtr())); |
| 883 return true; | 849 return true; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 process_handle.Take(), info, | 1004 process_handle.Take(), info, |
| 1039 base::MessageLoopProxy::current(), | 1005 base::MessageLoopProxy::current(), |
| 1040 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1006 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 1041 weak_factory_.GetWeakPtr())); | 1007 weak_factory_.GetWeakPtr())); |
| 1042 return true; | 1008 return true; |
| 1043 } | 1009 } |
| 1044 } | 1010 } |
| 1045 #endif | 1011 #endif |
| 1046 | 1012 |
| 1047 } // namespace nacl | 1013 } // namespace nacl |
| OLD | NEW |