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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 | 403 |
| 404 void NaClProcessHost::DebugContext::StopThread() { | 404 void NaClProcessHost::DebugContext::StopThread() { |
| 405 thread_->Stop(); | 405 thread_->Stop(); |
| 406 thread_.reset(); | 406 thread_.reset(); |
| 407 } | 407 } |
| 408 #endif | 408 #endif |
| 409 | 409 |
| 410 struct NaClProcessHost::NaClInternal { | 410 struct NaClProcessHost::NaClInternal { |
| 411 std::vector<nacl::Handle> sockets_for_renderer; | 411 std::vector<nacl::Handle> sockets_for_renderer; |
| 412 std::vector<nacl::Handle> sockets_for_sel_ldr; | 412 std::vector<nacl::Handle> sockets_for_sel_ldr; |
| 413 std::vector<nacl::FileDescriptor> handles_for_renderer; | |
| 413 }; | 414 }; |
| 414 | 415 |
| 415 // ----------------------------------------------------------------------------- | 416 // ----------------------------------------------------------------------------- |
| 416 | 417 |
| 417 NaClProcessHost::NaClProcessHost(const GURL& manifest_url) | 418 NaClProcessHost::NaClProcessHost(const GURL& manifest_url) |
| 418 : manifest_url_(manifest_url), | 419 : manifest_url_(manifest_url), |
| 419 #if defined(OS_WIN) | 420 #if defined(OS_WIN) |
| 420 process_launched_by_broker_(false), | 421 process_launched_by_broker_(false), |
| 421 #elif defined(OS_LINUX) | 422 #elif defined(OS_LINUX) |
| 422 wait_for_nacl_gdb_(false), | 423 wait_for_nacl_gdb_(false), |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 875 return true; | 876 return true; |
| 876 } | 877 } |
| 877 | 878 |
| 878 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { | 879 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { |
| 879 bool handled = true; | 880 bool handled = true; |
| 880 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) | 881 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) |
| 881 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, | 882 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, |
| 882 OnQueryKnownToValidate) | 883 OnQueryKnownToValidate) |
| 883 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, | 884 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, |
| 884 OnSetKnownToValidate) | 885 OnSetKnownToValidate) |
| 886 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated, | |
| 887 OnPpapiChannelCreated) | |
| 885 IPC_MESSAGE_UNHANDLED(handled = false) | 888 IPC_MESSAGE_UNHANDLED(handled = false) |
| 886 IPC_END_MESSAGE_MAP() | 889 IPC_END_MESSAGE_MAP() |
| 887 return handled; | 890 return handled; |
| 888 } | 891 } |
| 889 | 892 |
| 890 void NaClProcessHost::OnProcessCrashed(int exit_code) { | 893 void NaClProcessHost::OnProcessCrashed(int exit_code) { |
| 891 std::string message = base::StringPrintf( | 894 std::string message = base::StringPrintf( |
| 892 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); | 895 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); |
| 893 LOG(ERROR) << message; | 896 LOG(ERROR) << message; |
| 894 } | 897 } |
| 895 | 898 |
| 896 void NaClProcessHost::OnProcessLaunched() { | 899 void NaClProcessHost::OnProcessLaunched() { |
| 897 if (!StartWithLaunchedProcess()) | 900 if (!StartWithLaunchedProcess()) |
| 898 delete this; | 901 delete this; |
| 899 } | 902 } |
| 900 | 903 |
| 901 // The asynchronous attempt to get the IRT file open has completed. | 904 // The asynchronous attempt to get the IRT file open has completed. |
| 902 void NaClProcessHost::IrtReady() { | 905 void NaClProcessHost::IrtReady() { |
| 903 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 906 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 904 if (!nacl_browser->IrtAvailable() || !SendStart()) { | 907 if (!nacl_browser->IrtAvailable() || !SendStart()) { |
| 905 DLOG(ERROR) << "Cannot launch NaCl process"; | 908 DLOG(ERROR) << "Cannot launch NaCl process"; |
| 906 delete this; | 909 delete this; |
| 907 } | 910 } |
| 908 } | 911 } |
| 909 | 912 |
| 910 bool NaClProcessHost::ReplyToRenderer() { | 913 bool NaClProcessHost::SendStart() { |
| 911 std::vector<nacl::FileDescriptor> handles_for_renderer; | |
| 912 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { | 914 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
| 913 #if defined(OS_WIN) | 915 #if defined(OS_WIN) |
| 914 // Copy the handle into the renderer process. | 916 // Copy the handle into the renderer process. |
| 915 HANDLE handle_in_renderer; | 917 HANDLE handle_in_renderer; |
| 916 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 918 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
| 917 reinterpret_cast<HANDLE>( | 919 reinterpret_cast<HANDLE>( |
| 918 internal_->sockets_for_renderer[i]), | 920 internal_->sockets_for_renderer[i]), |
| 919 chrome_render_message_filter_->peer_handle(), | 921 chrome_render_message_filter_->peer_handle(), |
| 920 &handle_in_renderer, | 922 &handle_in_renderer, |
| 921 0, // Unused given DUPLICATE_SAME_ACCESS. | 923 0, // Unused given DUPLICATE_SAME_ACCESS. |
| 922 FALSE, | 924 FALSE, |
| 923 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 925 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
| 924 DLOG(ERROR) << "DuplicateHandle() failed"; | 926 DLOG(ERROR) << "DuplicateHandle() failed"; |
| 925 return false; | 927 return false; |
| 926 } | 928 } |
| 927 handles_for_renderer.push_back( | 929 internal_->handles_for_renderer.push_back( |
| 928 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); | 930 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); |
| 929 #else | 931 #else |
| 930 // No need to dup the imc_handle - we don't pass it anywhere else so | 932 // No need to dup the imc_handle - we don't pass it anywhere else so |
| 931 // it cannot be closed. | 933 // it cannot be closed. |
| 932 nacl::FileDescriptor imc_handle; | 934 nacl::FileDescriptor imc_handle; |
| 933 imc_handle.fd = internal_->sockets_for_renderer[i]; | 935 imc_handle.fd = internal_->sockets_for_renderer[i]; |
| 934 imc_handle.auto_close = true; | 936 imc_handle.auto_close = true; |
| 935 handles_for_renderer.push_back(imc_handle); | 937 internal_->handles_for_renderer.push_back(imc_handle); |
| 936 #endif | 938 #endif |
| 937 } | 939 } |
| 938 | 940 |
| 941 const ChildProcessData& data = process_->GetData(); | |
|
dmichael (off chromium)
2012/05/04 22:51:42
Why did you move this farther from where it's firs
bbudge
2012/05/07 18:08:53
Done.
| |
| 939 #if defined(OS_WIN) | 942 #if defined(OS_WIN) |
| 940 // If we are on 64-bit Windows, the NaCl process's sandbox is | 943 // If we are on 64-bit Windows, the NaCl process's sandbox is |
| 941 // managed by a different process from the renderer's sandbox. We | 944 // managed by a different process from the renderer's sandbox. We |
| 942 // need to inform the renderer's sandbox about the NaCl process so | 945 // need to inform the renderer's sandbox about the NaCl process so |
| 943 // that the renderer can send handles to the NaCl process using | 946 // that the renderer can send handles to the NaCl process using |
| 944 // BrokerDuplicateHandle(). | 947 // BrokerDuplicateHandle(). |
| 945 if (RunningOnWOW64()) { | 948 if (RunningOnWOW64()) { |
| 946 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { | 949 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { |
| 947 DLOG(ERROR) << "Failed to add NaCl process PID"; | 950 DLOG(ERROR) << "Failed to add NaCl process PID"; |
| 948 return false; | 951 return false; |
| 949 } | 952 } |
| 950 } | 953 } |
| 951 #endif | 954 #endif |
| 952 | 955 |
| 953 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | |
| 954 reply_msg_, handles_for_renderer); | |
| 955 chrome_render_message_filter_->Send(reply_msg_); | |
| 956 chrome_render_message_filter_ = NULL; | |
| 957 reply_msg_ = NULL; | |
| 958 internal_->sockets_for_renderer.clear(); | |
| 959 return true; | |
| 960 } | |
| 961 | |
| 962 bool NaClProcessHost::StartNaClExecution() { | |
| 963 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 956 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 964 | 957 |
| 965 nacl::NaClStartParams params; | 958 nacl::NaClStartParams params; |
| 966 params.validation_cache_key = nacl_browser->GetValidatorCacheKey(); | 959 params.validation_cache_key = nacl_browser->GetValidatorCacheKey(); |
| 967 params.version = chrome::VersionInfo().CreateVersionString(); | 960 params.version = chrome::VersionInfo().CreateVersionString(); |
| 968 params.enable_exception_handling = enable_exception_handling_; | 961 params.enable_exception_handling = enable_exception_handling_; |
| 969 | 962 |
| 970 base::PlatformFile irt_file = nacl_browser->IrtFile(); | 963 base::PlatformFile irt_file = nacl_browser->IrtFile(); |
| 971 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); | 964 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); |
| 972 | 965 |
| 973 const ChildProcessData& data = process_->GetData(); | |
| 974 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { | 966 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
| 975 if (!ShareHandleToSelLdr(data.handle, | 967 if (!ShareHandleToSelLdr(data.handle, |
| 976 internal_->sockets_for_sel_ldr[i], true, | 968 internal_->sockets_for_sel_ldr[i], true, |
| 977 ¶ms.handles)) { | 969 ¶ms.handles)) { |
| 978 return false; | 970 return false; |
| 979 } | 971 } |
| 980 } | 972 } |
| 981 | 973 |
| 982 // Send over the IRT file handle. We don't close our own copy! | 974 // Send over the IRT file handle. We don't close our own copy! |
| 983 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) | 975 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 999 nacl::FileDescriptor memory_fd; | 991 nacl::FileDescriptor memory_fd; |
| 1000 memory_fd.fd = dup(memory_buffer.handle().fd); | 992 memory_fd.fd = dup(memory_buffer.handle().fd); |
| 1001 if (memory_fd.fd < 0) { | 993 if (memory_fd.fd < 0) { |
| 1002 DLOG(ERROR) << "Failed to dup() a file descriptor"; | 994 DLOG(ERROR) << "Failed to dup() a file descriptor"; |
| 1003 return false; | 995 return false; |
| 1004 } | 996 } |
| 1005 memory_fd.auto_close = true; | 997 memory_fd.auto_close = true; |
| 1006 params.handles.push_back(memory_fd); | 998 params.handles.push_back(memory_fd); |
| 1007 #endif | 999 #endif |
| 1008 | 1000 |
| 1001 // The start message should only be sent once we are sure we won't delete | |
| 1002 // ourselves. | |
| 1009 IPC::Message* start_message = new NaClProcessMsg_Start(params); | 1003 IPC::Message* start_message = new NaClProcessMsg_Start(params); |
| 1010 #if defined(OS_WIN) | 1004 #if defined(OS_WIN) |
| 1011 if (debug_context_ != NULL) { | 1005 if (debug_context_ != NULL) { |
| 1012 debug_context_->SetStartMessage(start_message); | 1006 debug_context_->SetStartMessage(start_message); |
| 1013 debug_context_->SendStartMessage(); | 1007 debug_context_->SendStartMessage(); |
| 1014 } else { | 1008 } else { |
| 1015 process_->Send(start_message); | 1009 process_->Send(start_message); |
| 1016 } | 1010 } |
| 1017 #else | 1011 #else |
| 1018 process_->Send(start_message); | 1012 process_->Send(start_message); |
| 1019 #endif | 1013 #endif |
| 1020 | 1014 |
| 1021 internal_->sockets_for_sel_ldr.clear(); | 1015 internal_->sockets_for_sel_ldr.clear(); |
| 1022 return true; | 1016 return true; |
| 1023 } | 1017 } |
| 1024 | 1018 |
| 1025 bool NaClProcessHost::SendStart() { | 1019 void NaClProcessHost::OnPpapiChannelCreated( |
| 1026 return ReplyToRenderer() && StartNaClExecution(); | 1020 const IPC::ChannelHandle& channel_handle) { |
| 1021 // Now that the server end of the channel has been created, send the reply to | |
| 1022 // the renderer. | |
| 1023 base::ProcessId nacl_process_id = base::GetProcId(process_->GetData().handle); | |
| 1024 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | |
| 1025 reply_msg_, internal_->handles_for_renderer, channel_handle, | |
| 1026 base::kNullProcessHandle, nacl_process_id); | |
| 1027 chrome_render_message_filter_->Send(reply_msg_); | |
| 1028 chrome_render_message_filter_ = NULL; | |
| 1029 reply_msg_ = NULL; | |
| 1030 | |
| 1031 internal_->sockets_for_renderer.clear(); | |
| 1032 internal_->handles_for_renderer.clear(); | |
| 1027 } | 1033 } |
| 1028 | 1034 |
| 1029 bool NaClProcessHost::StartWithLaunchedProcess() { | 1035 bool NaClProcessHost::StartWithLaunchedProcess() { |
| 1030 #if defined(OS_LINUX) | 1036 #if defined(OS_LINUX) |
| 1031 if (wait_for_nacl_gdb_) { | 1037 if (wait_for_nacl_gdb_) { |
| 1032 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { | 1038 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { |
| 1033 // We will be called with wait_for_nacl_gdb_ = false once debugger is | 1039 // We will be called with wait_for_nacl_gdb_ = false once debugger is |
| 1034 // attached to the program. | 1040 // attached to the program. |
| 1035 return true; | 1041 return true; |
| 1036 } | 1042 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1049 } | 1055 } |
| 1050 | 1056 |
| 1051 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, | 1057 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, |
| 1052 bool* result) { | 1058 bool* result) { |
| 1053 *result = NaClBrowser::GetInstance()->QueryKnownToValidate(signature); | 1059 *result = NaClBrowser::GetInstance()->QueryKnownToValidate(signature); |
| 1054 } | 1060 } |
| 1055 | 1061 |
| 1056 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { | 1062 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { |
| 1057 NaClBrowser::GetInstance()->SetKnownToValidate(signature); | 1063 NaClBrowser::GetInstance()->SetKnownToValidate(signature); |
| 1058 } | 1064 } |
| OLD | NEW |