| 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 | 94 |
| 95 void SetCloseOnExec(nacl::Handle fd) { | 95 void SetCloseOnExec(nacl::Handle fd) { |
| 96 #if defined(OS_POSIX) | 96 #if defined(OS_POSIX) |
| 97 int flags = fcntl(fd, F_GETFD); | 97 int flags = fcntl(fd, F_GETFD); |
| 98 CHECK_NE(flags, -1); | 98 CHECK_NE(flags, -1); |
| 99 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | 99 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
| 100 CHECK_EQ(rc, 0); | 100 CHECK_EQ(rc, 0); |
| 101 #endif | 101 #endif |
| 102 } | 102 } |
| 103 | 103 |
| 104 bool SendHandleToSelLdr( | 104 bool ShareHandleToSelLdr( |
| 105 base::ProcessHandle processh, | 105 base::ProcessHandle processh, |
| 106 nacl::Handle sourceh, | 106 nacl::Handle sourceh, |
| 107 bool close_source, | 107 bool close_source, |
| 108 std::vector<nacl::FileDescriptor> *handles_for_sel_ldr) { | 108 std::vector<nacl::FileDescriptor> *handles_for_sel_ldr) { |
| 109 #if defined(OS_WIN) | 109 #if defined(OS_WIN) |
| 110 HANDLE channel; | 110 HANDLE channel; |
| 111 int flags = DUPLICATE_SAME_ACCESS; | 111 int flags = DUPLICATE_SAME_ACCESS; |
| 112 if (close_source) | 112 if (close_source) |
| 113 flags |= DUPLICATE_CLOSE_SOURCE; | 113 flags |= DUPLICATE_CLOSE_SOURCE; |
| 114 if (!DuplicateHandle(GetCurrentProcess(), | 114 if (!DuplicateHandle(GetCurrentProcess(), |
| (...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 | 873 |
| 874 // The asynchronous attempt to get the IRT file open has completed. | 874 // The asynchronous attempt to get the IRT file open has completed. |
| 875 void NaClProcessHost::IrtReady() { | 875 void NaClProcessHost::IrtReady() { |
| 876 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 876 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 877 if (!nacl_browser->IrtAvailable() || !SendStart()) { | 877 if (!nacl_browser->IrtAvailable() || !SendStart()) { |
| 878 DLOG(ERROR) << "Cannot launch NaCl process"; | 878 DLOG(ERROR) << "Cannot launch NaCl process"; |
| 879 delete this; | 879 delete this; |
| 880 } | 880 } |
| 881 } | 881 } |
| 882 | 882 |
| 883 bool NaClProcessHost::SendStart() { | 883 bool NaClProcessHost::ReplyToRenderer() { |
| 884 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | |
| 885 base::PlatformFile irt_file = nacl_browser->IrtFile(); | |
| 886 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); | |
| 887 | |
| 888 std::vector<nacl::FileDescriptor> handles_for_renderer; | 884 std::vector<nacl::FileDescriptor> handles_for_renderer; |
| 889 base::ProcessHandle nacl_process_handle; | |
| 890 | |
| 891 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { | 885 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
| 892 #if defined(OS_WIN) | 886 #if defined(OS_WIN) |
| 893 // Copy the handle into the renderer process. | 887 // Copy the handle into the renderer process. |
| 894 HANDLE handle_in_renderer; | 888 HANDLE handle_in_renderer; |
| 895 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 889 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
| 896 reinterpret_cast<HANDLE>( | 890 reinterpret_cast<HANDLE>( |
| 897 internal_->sockets_for_renderer[i]), | 891 internal_->sockets_for_renderer[i]), |
| 898 chrome_render_message_filter_->peer_handle(), | 892 chrome_render_message_filter_->peer_handle(), |
| 899 &handle_in_renderer, | 893 &handle_in_renderer, |
| 900 0, // Unused given DUPLICATE_SAME_ACCESS. | 894 0, // Unused given DUPLICATE_SAME_ACCESS. |
| 901 FALSE, | 895 FALSE, |
| 902 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 896 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
| 903 DLOG(ERROR) << "DuplicateHandle() failed"; | 897 DLOG(ERROR) << "DuplicateHandle() failed"; |
| 904 return false; | 898 return false; |
| 905 } | 899 } |
| 906 handles_for_renderer.push_back( | 900 handles_for_renderer.push_back( |
| 907 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); | 901 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); |
| 908 #else | 902 #else |
| 909 // No need to dup the imc_handle - we don't pass it anywhere else so | 903 // No need to dup the imc_handle - we don't pass it anywhere else so |
| 910 // it cannot be closed. | 904 // it cannot be closed. |
| 911 nacl::FileDescriptor imc_handle; | 905 nacl::FileDescriptor imc_handle; |
| 912 imc_handle.fd = internal_->sockets_for_renderer[i]; | 906 imc_handle.fd = internal_->sockets_for_renderer[i]; |
| 913 imc_handle.auto_close = true; | 907 imc_handle.auto_close = true; |
| 914 handles_for_renderer.push_back(imc_handle); | 908 handles_for_renderer.push_back(imc_handle); |
| 915 #endif | 909 #endif |
| 916 } | 910 } |
| 917 | 911 |
| 918 const ChildProcessData& data = process_->GetData(); | 912 const ChildProcessData& data = process_->GetData(); |
| 913 base::ProcessHandle nacl_process_handle; |
| 919 #if defined(OS_WIN) | 914 #if defined(OS_WIN) |
| 920 // Copy the process handle into the renderer process. | 915 // Copy the process handle into the renderer process. |
| 921 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 916 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
| 922 data.handle, | 917 data.handle, |
| 923 chrome_render_message_filter_->peer_handle(), | 918 chrome_render_message_filter_->peer_handle(), |
| 924 &nacl_process_handle, | 919 &nacl_process_handle, |
| 925 PROCESS_DUP_HANDLE, | 920 PROCESS_DUP_HANDLE, |
| 926 FALSE, | 921 FALSE, |
| 927 0)) { | 922 0)) { |
| 928 DLOG(ERROR) << "DuplicateHandle() failed"; | 923 DLOG(ERROR) << "DuplicateHandle() failed"; |
| 929 return false; | 924 return false; |
| 930 } | 925 } |
| 931 #else | 926 #else |
| 932 // We use pid as process handle on Posix | 927 // We use pid as process handle on Posix |
| 933 nacl_process_handle = data.handle; | 928 nacl_process_handle = data.handle; |
| 934 #endif | 929 #endif |
| 935 | 930 |
| 936 // Get the pid of the NaCl process | 931 // Get the pid of the NaCl process |
| 937 base::ProcessId nacl_process_id = base::GetProcId(data.handle); | 932 base::ProcessId nacl_process_id = base::GetProcId(data.handle); |
| 938 | 933 |
| 939 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | 934 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( |
| 940 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); | 935 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); |
| 941 chrome_render_message_filter_->Send(reply_msg_); | 936 chrome_render_message_filter_->Send(reply_msg_); |
| 942 chrome_render_message_filter_ = NULL; | 937 chrome_render_message_filter_ = NULL; |
| 943 reply_msg_ = NULL; | 938 reply_msg_ = NULL; |
| 944 internal_->sockets_for_renderer.clear(); | 939 internal_->sockets_for_renderer.clear(); |
| 940 return true; |
| 941 } |
| 945 | 942 |
| 946 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; | 943 bool NaClProcessHost::StartNaClExecution() { |
| 944 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 945 |
| 946 nacl::NaClStartParams params; |
| 947 params.validation_cache_key = nacl_browser->GetValidatorCacheKey(); |
| 948 params.version = chrome::VersionInfo().CreateVersionString(); |
| 949 params.enable_exception_handling = enable_exception_handling_; |
| 950 |
| 951 base::PlatformFile irt_file = nacl_browser->IrtFile(); |
| 952 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); |
| 953 |
| 954 const ChildProcessData& data = process_->GetData(); |
| 947 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { | 955 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
| 948 if (!SendHandleToSelLdr(data.handle, | 956 if (!ShareHandleToSelLdr(data.handle, |
| 949 internal_->sockets_for_sel_ldr[i], true, | 957 internal_->sockets_for_sel_ldr[i], true, |
| 950 &handles_for_sel_ldr)) { | 958 ¶ms.handles)) { |
| 951 return false; | 959 return false; |
| 952 } | 960 } |
| 953 } | 961 } |
| 954 | 962 |
| 955 // Send over the IRT file handle. We don't close our own copy! | 963 // Send over the IRT file handle. We don't close our own copy! |
| 956 if (!SendHandleToSelLdr(data.handle, irt_file, false, &handles_for_sel_ldr)) | 964 if (!ShareHandleToSelLdr(data.handle, irt_file, false, ¶ms.handles)) |
| 957 return false; | 965 return false; |
| 958 | 966 |
| 959 #if defined(OS_MACOSX) | 967 #if defined(OS_MACOSX) |
| 960 // For dynamic loading support, NaCl requires a file descriptor that | 968 // For dynamic loading support, NaCl requires a file descriptor that |
| 961 // was created in /tmp, since those created with shm_open() are not | 969 // was created in /tmp, since those created with shm_open() are not |
| 962 // mappable with PROT_EXEC. Rather than requiring an extra IPC | 970 // mappable with PROT_EXEC. Rather than requiring an extra IPC |
| 963 // round trip out of the sandbox, we create an FD here. | 971 // round trip out of the sandbox, we create an FD here. |
| 964 base::SharedMemory memory_buffer; | 972 base::SharedMemory memory_buffer; |
| 965 base::SharedMemoryCreateOptions options; | 973 base::SharedMemoryCreateOptions options; |
| 966 options.size = 1; | 974 options.size = 1; |
| 967 options.executable = true; | 975 options.executable = true; |
| 968 if (!memory_buffer.Create(options)) { | 976 if (!memory_buffer.Create(options)) { |
| 969 DLOG(ERROR) << "Failed to allocate memory buffer"; | 977 DLOG(ERROR) << "Failed to allocate memory buffer"; |
| 970 return false; | 978 return false; |
| 971 } | 979 } |
| 972 nacl::FileDescriptor memory_fd; | 980 nacl::FileDescriptor memory_fd; |
| 973 memory_fd.fd = dup(memory_buffer.handle().fd); | 981 memory_fd.fd = dup(memory_buffer.handle().fd); |
| 974 if (memory_fd.fd < 0) { | 982 if (memory_fd.fd < 0) { |
| 975 DLOG(ERROR) << "Failed to dup() a file descriptor"; | 983 DLOG(ERROR) << "Failed to dup() a file descriptor"; |
| 976 return false; | 984 return false; |
| 977 } | 985 } |
| 978 memory_fd.auto_close = true; | 986 memory_fd.auto_close = true; |
| 979 handles_for_sel_ldr.push_back(memory_fd); | 987 params.handles.push_back(memory_fd); |
| 980 #endif | 988 #endif |
| 981 | 989 |
| 982 // Sending the version string over IPC avoids linkage issues in cases where | 990 IPC::Message* start_message = new NaClProcessMsg_Start(params); |
| 983 // NaCl is not compiled into the main Chromium executable or DLL. | |
| 984 chrome::VersionInfo version_info; | |
| 985 IPC::Message* start_message = | |
| 986 new NaClProcessMsg_Start(handles_for_sel_ldr, | |
| 987 nacl_browser->GetValidatorCacheKey(), | |
| 988 version_info.CreateVersionString(), | |
| 989 enable_exception_handling_); | |
| 990 #if defined(OS_WIN) | 991 #if defined(OS_WIN) |
| 991 if (debug_context_ != NULL) { | 992 if (debug_context_ != NULL) { |
| 992 debug_context_->SetStartMessage(start_message); | 993 debug_context_->SetStartMessage(start_message); |
| 993 debug_context_->SendStartMessage(); | 994 debug_context_->SendStartMessage(); |
| 994 } else { | 995 } else { |
| 995 process_->Send(start_message); | 996 process_->Send(start_message); |
| 996 } | 997 } |
| 997 #else | 998 #else |
| 998 process_->Send(start_message); | 999 process_->Send(start_message); |
| 999 #endif | 1000 #endif |
| 1000 | 1001 |
| 1001 internal_->sockets_for_sel_ldr.clear(); | 1002 internal_->sockets_for_sel_ldr.clear(); |
| 1002 return true; | 1003 return true; |
| 1003 } | 1004 } |
| 1004 | 1005 |
| 1006 bool NaClProcessHost::SendStart() { |
| 1007 return ReplyToRenderer() && StartNaClExecution(); |
| 1008 } |
| 1009 |
| 1005 bool NaClProcessHost::StartWithLaunchedProcess() { | 1010 bool NaClProcessHost::StartWithLaunchedProcess() { |
| 1006 #if defined(OS_LINUX) | 1011 #if defined(OS_LINUX) |
| 1007 if (wait_for_nacl_gdb_) { | 1012 if (wait_for_nacl_gdb_) { |
| 1008 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { | 1013 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { |
| 1009 // We will be called with wait_for_nacl_gdb_ = false once debugger is | 1014 // We will be called with wait_for_nacl_gdb_ = false once debugger is |
| 1010 // attached to the program. | 1015 // attached to the program. |
| 1011 return true; | 1016 return true; |
| 1012 } | 1017 } |
| 1013 DLOG(ERROR) << "Failed to launch debugger"; | 1018 DLOG(ERROR) << "Failed to launch debugger"; |
| 1014 // Continue execution without debugger. | 1019 // Continue execution without debugger. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1025 } | 1030 } |
| 1026 | 1031 |
| 1027 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, | 1032 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, |
| 1028 bool* result) { | 1033 bool* result) { |
| 1029 *result = NaClBrowser::GetInstance()->QueryKnownToValidate(signature); | 1034 *result = NaClBrowser::GetInstance()->QueryKnownToValidate(signature); |
| 1030 } | 1035 } |
| 1031 | 1036 |
| 1032 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { | 1037 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { |
| 1033 NaClBrowser::GetInstance()->SetKnownToValidate(signature); | 1038 NaClBrowser::GetInstance()->SetKnownToValidate(signature); |
| 1034 } | 1039 } |
| OLD | NEW |