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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 bool nonsfi_mode_enabled = | 467 bool nonsfi_mode_enabled = |
468 nonsfi_mode_forced_by_command_line || nonsfi_mode_allowed; | 468 nonsfi_mode_forced_by_command_line || nonsfi_mode_allowed; |
469 | 469 |
470 if (!nonsfi_mode_enabled) { | 470 if (!nonsfi_mode_enabled) { |
471 SendErrorToRenderer( | 471 SendErrorToRenderer( |
472 "NaCl non-SFI mode is not available for this platform" | 472 "NaCl non-SFI mode is not available for this platform" |
473 " and NaCl module."); | 473 " and NaCl module."); |
474 delete this; | 474 delete this; |
475 return; | 475 return; |
476 } | 476 } |
477 | |
478 if (!enable_ppapi_proxy()) { | |
479 SendErrorToRenderer( | |
480 "PPAPI proxy must be enabled on NaCl in Non-SFI mode."); | |
481 delete this; | |
482 return; | |
483 } | |
477 } else { | 484 } else { |
478 // Rather than creating a socket pair in the renderer, and passing | 485 // Rather than creating a socket pair in the renderer, and passing |
479 // one side through the browser to sel_ldr, socket pairs are created | 486 // one side through the browser to sel_ldr, socket pairs are created |
480 // in the browser and then passed to the renderer and sel_ldr. | 487 // in the browser and then passed to the renderer and sel_ldr. |
481 // | 488 // |
482 // This is mainly for the benefit of Windows, where sockets cannot | 489 // This is mainly for the benefit of Windows, where sockets cannot |
483 // be passed in messages, but are copied via DuplicateHandle(). | 490 // be passed in messages, but are copied via DuplicateHandle(). |
484 // This means the sandboxed renderer cannot send handles to the | 491 // This means the sandboxed renderer cannot send handles to the |
485 // browser process. | 492 // browser process. |
486 | 493 |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
665 } | 672 } |
666 #endif | 673 #endif |
667 process_->Launch( | 674 process_->Launch( |
668 new NaClSandboxedProcessLauncherDelegate(process_->GetHost()), | 675 new NaClSandboxedProcessLauncherDelegate(process_->GetHost()), |
669 cmd_line.release(), | 676 cmd_line.release(), |
670 true); | 677 true); |
671 return true; | 678 return true; |
672 } | 679 } |
673 | 680 |
674 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { | 681 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { |
675 bool handled = true; | |
676 if (uses_nonsfi_mode_) { | 682 if (uses_nonsfi_mode_) { |
677 // IPC messages relating to NaCl's validation cache must not be exposed | 683 // IPC messages relating to NaCl's validation cache must not be exposed |
678 // in Non-SFI Mode, otherwise a Non-SFI nexe could use | 684 // in Non-SFI Mode, otherwise a Non-SFI nexe could use SetKnownToValidate |
679 // SetKnownToValidate to create a hole in the SFI sandbox. | 685 // to create a hole in the SFI sandbox. |
680 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | 686 // In Non-SFI mode, no message is expected. |
681 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, | 687 return false; |
682 OnPpapiChannelsCreated) | 688 } |
683 IPC_MESSAGE_UNHANDLED(handled = false) | 689 |
684 IPC_END_MESSAGE_MAP() | 690 bool handled = true; |
685 } else { | 691 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) |
686 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | 692 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, |
687 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, | 693 OnQueryKnownToValidate) |
688 OnQueryKnownToValidate) | 694 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, |
689 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, | 695 OnSetKnownToValidate) |
690 OnSetKnownToValidate) | 696 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileToken, |
691 IPC_MESSAGE_HANDLER(NaClProcessMsg_ResolveFileToken, | 697 OnResolveFileToken) |
692 OnResolveFileToken) | |
693 | 698 |
694 #if defined(OS_WIN) | 699 #if defined(OS_WIN) |
695 IPC_MESSAGE_HANDLER_DELAY_REPLY( | 700 IPC_MESSAGE_HANDLER_DELAY_REPLY( |
696 NaClProcessMsg_AttachDebugExceptionHandler, | 701 NaClProcessMsg_AttachDebugExceptionHandler, |
697 OnAttachDebugExceptionHandler) | 702 OnAttachDebugExceptionHandler) |
698 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected, | 703 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_DebugStubPortSelected, |
699 OnDebugStubPortSelected) | 704 OnDebugStubPortSelected) |
700 #endif | 705 #endif |
701 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, | 706 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelsCreated, |
702 OnPpapiChannelsCreated) | 707 OnPpapiChannelsCreated) |
703 IPC_MESSAGE_UNHANDLED(handled = false) | 708 IPC_MESSAGE_UNHANDLED(handled = false) |
704 IPC_END_MESSAGE_MAP() | 709 IPC_END_MESSAGE_MAP() |
705 } | |
706 return handled; | 710 return handled; |
707 } | 711 } |
708 | 712 |
709 void NaClProcessHost::OnProcessLaunched() { | 713 void NaClProcessHost::OnProcessLaunched() { |
710 if (!StartWithLaunchedProcess()) | 714 if (!StartWithLaunchedProcess()) |
711 delete this; | 715 delete this; |
712 } | 716 } |
713 | 717 |
714 // Called when the NaClBrowser singleton has been fully initialized. | 718 // Called when the NaClBrowser singleton has been fully initialized. |
715 void NaClProcessHost::OnResourcesReady() { | 719 void NaClProcessHost::OnResourcesReady() { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
865 // Currently, non-SFI mode is supported only on Linux. | 869 // Currently, non-SFI mode is supported only on Linux. |
866 #if defined(OS_LINUX) | 870 #if defined(OS_LINUX) |
867 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is | 871 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is |
868 // not created. | 872 // not created. |
869 DCHECK(!socket_for_sel_ldr_.IsValid()); | 873 DCHECK(!socket_for_sel_ldr_.IsValid()); |
870 #endif | 874 #endif |
871 if (enable_nacl_debug) { | 875 if (enable_nacl_debug) { |
872 base::ProcessId pid = base::GetProcId(process_->GetData().handle); | 876 base::ProcessId pid = base::GetProcId(process_->GetData().handle); |
873 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; | 877 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; |
874 } | 878 } |
879 DCHECK(params.enable_ipc_proxy); | |
Mark Seaborn
2015/05/13 06:51:11
Nit: This isn't needed now, since you check this b
hidehiko
2015/05/13 14:44:48
Done.
| |
875 } else { | 880 } else { |
876 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); | 881 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); |
877 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); | 882 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); |
878 params.version = NaClBrowser::GetDelegate()->GetVersionString(); | 883 params.version = NaClBrowser::GetDelegate()->GetVersionString(); |
879 params.enable_debug_stub = enable_nacl_debug; | 884 params.enable_debug_stub = enable_nacl_debug; |
880 | 885 |
881 const ChildProcessData& data = process_->GetData(); | 886 const ChildProcessData& data = process_->GetData(); |
882 params.imc_bootstrap_handle = | 887 params.imc_bootstrap_handle = |
883 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle); | 888 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), data.handle); |
884 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) { | 889 if (params.imc_bootstrap_handle == IPC::InvalidPlatformFileForTransit()) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
968 true /* is_executable */), | 973 true /* is_executable */), |
969 base::Bind(&NaClProcessHost::StartNaClFileResolved, | 974 base::Bind(&NaClProcessHost::StartNaClFileResolved, |
970 weak_factory_.GetWeakPtr(), | 975 weak_factory_.GetWeakPtr(), |
971 params, | 976 params, |
972 file_path))) { | 977 file_path))) { |
973 return true; | 978 return true; |
974 } | 979 } |
975 } | 980 } |
976 } | 981 } |
977 | 982 |
978 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), | 983 StartNaClFileResolved(params, base::FilePath(), base::File()); |
979 process_->GetData().handle); | |
980 process_->Send(new NaClProcessMsg_Start(params)); | |
981 return true; | 984 return true; |
982 } | 985 } |
983 | 986 |
984 void NaClProcessHost::StartNaClFileResolved( | 987 void NaClProcessHost::StartNaClFileResolved( |
985 NaClStartParams params, | 988 NaClStartParams params, |
986 const base::FilePath& file_path, | 989 const base::FilePath& file_path, |
987 base::File checked_nexe_file) { | 990 base::File checked_nexe_file) { |
988 if (checked_nexe_file.IsValid()) { | 991 if (checked_nexe_file.IsValid()) { |
989 // Release the file received from the renderer. This has to be done on a | 992 // Release the file received from the renderer. This has to be done on a |
990 // thread where IO is permitted, though. | 993 // thread where IO is permitted, though. |
991 content::BrowserThread::GetBlockingPool()->PostTask( | 994 content::BrowserThread::GetBlockingPool()->PostTask( |
992 FROM_HERE, | 995 FROM_HERE, |
993 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); | 996 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); |
994 params.nexe_file_path_metadata = file_path; | 997 params.nexe_file_path_metadata = file_path; |
995 params.nexe_file = IPC::TakeFileHandleForProcess( | 998 params.nexe_file = IPC::TakeFileHandleForProcess( |
996 checked_nexe_file.Pass(), process_->GetData().handle); | 999 checked_nexe_file.Pass(), process_->GetData().handle); |
997 } else { | 1000 } else { |
998 params.nexe_file = IPC::TakeFileHandleForProcess( | 1001 params.nexe_file = IPC::TakeFileHandleForProcess( |
999 nexe_file_.Pass(), process_->GetData().handle); | 1002 nexe_file_.Pass(), process_->GetData().handle); |
1000 } | 1003 } |
1004 | |
1005 #if defined(OS_LINUX) | |
1006 // In Non-SFI mode, create socket pairs for IPC channels here, unlike in | |
1007 // SFI-mode, in which those channels are created in nacl_listener.cc. | |
1008 // This is for security hardening. We can then prohibit the socketpair() | |
1009 // system call in nacl_helper and nacl_helper_nonsfi. | |
1010 if (uses_nonsfi_mode_) { | |
1011 // Note: here, because some FDs/handles for the NaCl loader process are | |
1012 // already opened, they are transferred to NaCl loader process even if | |
1013 // an error occurs first. It is because this is the simplest way to | |
1014 // ensure that these FDs/handles don't get leaked and that the NaCl loader | |
1015 // process will exit properly. | |
1016 bool has_error = false; | |
1017 | |
1018 // Note: this check is redundant. We check this earlier. | |
1019 DCHECK(params.enable_ipc_proxy); | |
1020 | |
1021 ScopedChannelHandle ppapi_browser_server_channel_handle; | |
1022 ScopedChannelHandle ppapi_browser_client_channel_handle; | |
1023 ScopedChannelHandle ppapi_renderer_server_channel_handle; | |
1024 ScopedChannelHandle ppapi_renderer_client_channel_handle; | |
1025 ScopedChannelHandle trusted_service_server_channel_handle; | |
1026 ScopedChannelHandle trusted_service_client_channel_handle; | |
1027 ScopedChannelHandle manifest_service_server_channel_handle; | |
1028 ScopedChannelHandle manifest_service_client_channel_handle; | |
1029 | |
1030 if (!CreateChannelHandlePair(&ppapi_browser_server_channel_handle, | |
1031 &ppapi_browser_client_channel_handle) || | |
1032 !CreateChannelHandlePair(&ppapi_renderer_server_channel_handle, | |
1033 &ppapi_renderer_client_channel_handle) || | |
1034 !CreateChannelHandlePair(&trusted_service_server_channel_handle, | |
1035 &trusted_service_client_channel_handle) || | |
1036 !CreateChannelHandlePair(&manifest_service_server_channel_handle, | |
1037 &manifest_service_client_channel_handle)) { | |
1038 SendErrorToRenderer("Failed to create socket pairs."); | |
1039 has_error = true; | |
1040 } | |
1041 | |
1042 if (!has_error && | |
1043 !StartPPAPIProxy(ppapi_browser_client_channel_handle.Pass())) { | |
1044 SendErrorToRenderer("Failed to start browser PPAPI proxy."); | |
1045 has_error = true; | |
1046 } | |
1047 | |
1048 if (!has_error) { | |
1049 // On success, send back a success message to the renderer process, | |
1050 // and transfer the channel handles for the NaCl loader process to | |
1051 // |params|. | |
1052 ReplyToRenderer(ppapi_renderer_client_channel_handle.Pass(), | |
1053 trusted_service_client_channel_handle.Pass(), | |
1054 manifest_service_client_channel_handle.Pass()); | |
1055 params.ppapi_browser_channel_handle = | |
1056 ppapi_browser_server_channel_handle.release(); | |
1057 params.ppapi_renderer_channel_handle = | |
1058 ppapi_renderer_server_channel_handle.release(); | |
1059 params.trusted_service_channel_handle = | |
1060 trusted_service_server_channel_handle.release(); | |
1061 params.manifest_service_channel_handle = | |
1062 manifest_service_server_channel_handle.release(); | |
1063 } | |
1064 } | |
1065 #endif | |
1066 | |
1001 process_->Send(new NaClProcessMsg_Start(params)); | 1067 process_->Send(new NaClProcessMsg_Start(params)); |
1002 } | 1068 } |
1003 | 1069 |
1004 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is | 1070 #if defined(OS_LINUX) |
1005 // received. | 1071 // static |
1006 void NaClProcessHost::OnPpapiChannelsCreated( | 1072 bool NaClProcessHost::CreateChannelHandlePair( |
1007 const IPC::ChannelHandle& raw_browser_channel_handle, | 1073 ScopedChannelHandle* channel_handle1, |
1008 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle, | 1074 ScopedChannelHandle* channel_handle2) { |
1009 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle, | 1075 DCHECK(channel_handle1); |
1010 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { | 1076 DCHECK(channel_handle2); |
1011 ScopedChannelHandle browser_channel_handle(raw_browser_channel_handle); | |
1012 ScopedChannelHandle ppapi_renderer_channel_handle( | |
1013 raw_ppapi_renderer_channel_handle); | |
1014 ScopedChannelHandle trusted_renderer_channel_handle( | |
1015 raw_trusted_renderer_channel_handle); | |
1016 ScopedChannelHandle manifest_service_channel_handle( | |
1017 raw_manifest_service_channel_handle); | |
1018 | 1077 |
1019 if (!enable_ppapi_proxy()) { | 1078 int fd1 = -1; |
1020 ReplyToRenderer(ScopedChannelHandle(), | 1079 int fd2 = -1; |
1021 trusted_renderer_channel_handle.Pass(), | 1080 if (!IPC::SocketPair(&fd1, &fd2)) { |
1022 manifest_service_channel_handle.Pass()); | 1081 return false; |
1023 return; | |
1024 } | 1082 } |
1025 | 1083 |
1084 IPC::ChannelHandle handle = IPC::Channel::GenerateVerifiedChannelID("nacl"); | |
1085 handle.socket = base::FileDescriptor(fd1, true); | |
1086 channel_handle1->reset(handle); | |
1087 handle.socket = base::FileDescriptor(fd2, true); | |
1088 channel_handle2->reset(handle); | |
1089 return true; | |
1090 } | |
1091 #endif | |
1092 | |
1093 bool NaClProcessHost::StartPPAPIProxy(ScopedChannelHandle channel_handle) { | |
1026 if (ipc_proxy_channel_.get()) { | 1094 if (ipc_proxy_channel_.get()) { |
1027 // Attempt to open more than 1 browser channel is not supported. | 1095 // Attempt to open more than 1 browser channel is not supported. |
1028 // Shut down the NaCl process. | 1096 // Shut down the NaCl process. |
1029 process_->GetHost()->ForceShutdown(); | 1097 process_->GetHost()->ForceShutdown(); |
1030 return; | 1098 return false; |
1031 } | 1099 } |
1032 | 1100 |
1033 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); | 1101 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); |
1034 | 1102 |
1035 ipc_proxy_channel_ = | 1103 ipc_proxy_channel_ = IPC::ChannelProxy::Create( |
1036 IPC::ChannelProxy::Create(browser_channel_handle.release(), | 1104 channel_handle.release(), |
1037 IPC::Channel::MODE_CLIENT, | 1105 IPC::Channel::MODE_CLIENT, |
1038 NULL, | 1106 NULL, |
1039 base::MessageLoopProxy::current().get()); | 1107 base::MessageLoopProxy::current().get()); |
1040 // Create the browser ppapi host and enable PPAPI message dispatching to the | 1108 // Create the browser ppapi host and enable PPAPI message dispatching to the |
1041 // browser process. | 1109 // browser process. |
1042 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( | 1110 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( |
1043 ipc_proxy_channel_.get(), // sender | 1111 ipc_proxy_channel_.get(), // sender |
1044 permissions_, | 1112 permissions_, |
1045 process_->GetData().handle, | 1113 process_->GetData().handle, |
1046 ipc_proxy_channel_.get(), | 1114 ipc_proxy_channel_.get(), |
1047 nacl_host_message_filter_->render_process_id(), | 1115 nacl_host_message_filter_->render_process_id(), |
1048 render_view_id_, | 1116 render_view_id_, |
1049 profile_directory_)); | 1117 profile_directory_)); |
(...skipping 19 matching lines...) Expand all Loading... | |
1069 } | 1137 } |
1070 } | 1138 } |
1071 | 1139 |
1072 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( | 1140 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( |
1073 scoped_ptr<ppapi::host::HostFactory>( | 1141 scoped_ptr<ppapi::host::HostFactory>( |
1074 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( | 1142 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( |
1075 ppapi_host_.get()))); | 1143 ppapi_host_.get()))); |
1076 | 1144 |
1077 // Send a message to initialize the IPC dispatchers in the NaCl plugin. | 1145 // Send a message to initialize the IPC dispatchers in the NaCl plugin. |
1078 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); | 1146 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); |
1147 return true; | |
1148 } | |
1149 | |
1150 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is | |
1151 // received. | |
1152 void NaClProcessHost::OnPpapiChannelsCreated( | |
1153 const IPC::ChannelHandle& raw_ppapi_browser_channel_handle, | |
1154 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle, | |
1155 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle, | |
1156 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { | |
1157 ScopedChannelHandle ppapi_browser_channel_handle( | |
1158 raw_ppapi_browser_channel_handle); | |
1159 ScopedChannelHandle ppapi_renderer_channel_handle( | |
1160 raw_ppapi_renderer_channel_handle); | |
1161 ScopedChannelHandle trusted_renderer_channel_handle( | |
1162 raw_trusted_renderer_channel_handle); | |
1163 ScopedChannelHandle manifest_service_channel_handle( | |
1164 raw_manifest_service_channel_handle); | |
1165 | |
1166 if (enable_ppapi_proxy()) { | |
1167 if (!StartPPAPIProxy(ppapi_browser_channel_handle.Pass())) { | |
1168 SendErrorToRenderer("Browser PPAPI proxy could not start."); | |
1169 return; | |
1170 } | |
1171 } else { | |
1172 // If PPAPI proxy is disabled, channel handles should be invalid. | |
1173 DCHECK(ppapi_browser_channel_handle.get().name.empty()); | |
1174 DCHECK(ppapi_renderer_channel_handle.get().name.empty()); | |
1175 // Invalidate, just in case. | |
1176 ppapi_browser_channel_handle.reset(); | |
1177 ppapi_renderer_channel_handle.reset(); | |
1178 } | |
1079 | 1179 |
1080 // Let the renderer know that the IPC channels are established. | 1180 // Let the renderer know that the IPC channels are established. |
1081 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(), | 1181 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(), |
1082 trusted_renderer_channel_handle.Pass(), | 1182 trusted_renderer_channel_handle.Pass(), |
1083 manifest_service_channel_handle.Pass()); | 1183 manifest_service_channel_handle.Pass()); |
1084 } | 1184 } |
1085 | 1185 |
1086 bool NaClProcessHost::StartWithLaunchedProcess() { | 1186 bool NaClProcessHost::StartWithLaunchedProcess() { |
1087 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 1187 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
1088 | 1188 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1254 process.Pass(), info, | 1354 process.Pass(), info, |
1255 base::MessageLoopProxy::current(), | 1355 base::MessageLoopProxy::current(), |
1256 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1356 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
1257 weak_factory_.GetWeakPtr())); | 1357 weak_factory_.GetWeakPtr())); |
1258 return true; | 1358 return true; |
1259 } | 1359 } |
1260 } | 1360 } |
1261 #endif | 1361 #endif |
1262 | 1362 |
1263 } // namespace nacl | 1363 } // namespace nacl |
OLD | NEW |