Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 10020002: Pass the nacl start parameters as a struct. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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::StartNaClExecution() {
Mark Seaborn 2012/04/07 00:23:34 The ordering of the file would be more logical if
884 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 884 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
885
886 nacl::NaClStartParams params;
887 params.validation_cache_key = nacl_browser->GetValidatorCacheKey();
888 params.version = chrome::VersionInfo().CreateVersionString();
889 params.enable_exception_handling = enable_exception_handling_;
890
885 base::PlatformFile irt_file = nacl_browser->IrtFile(); 891 base::PlatformFile irt_file = nacl_browser->IrtFile();
886 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); 892 CHECK_NE(irt_file, base::kInvalidPlatformFileValue);
887 893
894 const ChildProcessData& data = process_->GetData();
895 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
896 if (!ShareHandleToSelLdr(data.handle,
897 internal_->sockets_for_sel_ldr[i], true,
898 &params.handles)) {
899 return false;
900 }
901 }
902
903 // Send over the IRT file handle. We don't close our own copy!
904 if (!ShareHandleToSelLdr(data.handle, irt_file, false, &params.handles))
905 return false;
906
907 #if defined(OS_MACOSX)
908 // For dynamic loading support, NaCl requires a file descriptor that
909 // was created in /tmp, since those created with shm_open() are not
910 // mappable with PROT_EXEC. Rather than requiring an extra IPC
911 // round trip out of the sandbox, we create an FD here.
912 base::SharedMemory memory_buffer;
913 base::SharedMemoryCreateOptions options;
914 options.size = 1;
915 options.executable = true;
916 if (!memory_buffer.Create(options)) {
917 DLOG(ERROR) << "Failed to allocate memory buffer";
918 return false;
919 }
920 nacl::FileDescriptor memory_fd;
921 memory_fd.fd = dup(memory_buffer.handle().fd);
922 if (memory_fd.fd < 0) {
923 DLOG(ERROR) << "Failed to dup() a file descriptor";
924 return false;
925 }
926 memory_fd.auto_close = true;
927 params.handles.push_back(memory_fd);
928 #endif
929
930 IPC::Message* start_message = new NaClProcessMsg_Start(params);
931 #if defined(OS_WIN)
932 if (debug_context_ != NULL) {
933 debug_context_->SetStartMessage(start_message);
934 debug_context_->SendStartMessage();
935 } else {
936 process_->Send(start_message);
937 }
938 #else
939 process_->Send(start_message);
940 #endif
941
942 internal_->sockets_for_sel_ldr.clear();
943 return true;
944 }
945
946 bool NaClProcessHost::ReplyToRenderer() {
888 std::vector<nacl::FileDescriptor> handles_for_renderer; 947 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++) { 948 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
892 #if defined(OS_WIN) 949 #if defined(OS_WIN)
893 // Copy the handle into the renderer process. 950 // Copy the handle into the renderer process.
894 HANDLE handle_in_renderer; 951 HANDLE handle_in_renderer;
895 if (!DuplicateHandle(base::GetCurrentProcessHandle(), 952 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
896 reinterpret_cast<HANDLE>( 953 reinterpret_cast<HANDLE>(
897 internal_->sockets_for_renderer[i]), 954 internal_->sockets_for_renderer[i]),
898 chrome_render_message_filter_->peer_handle(), 955 chrome_render_message_filter_->peer_handle(),
899 &handle_in_renderer, 956 &handle_in_renderer,
900 0, // Unused given DUPLICATE_SAME_ACCESS. 957 0, // Unused given DUPLICATE_SAME_ACCESS.
901 FALSE, 958 FALSE,
902 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 959 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
903 DLOG(ERROR) << "DuplicateHandle() failed"; 960 DLOG(ERROR) << "DuplicateHandle() failed";
904 return false; 961 return false;
905 } 962 }
906 handles_for_renderer.push_back( 963 handles_for_renderer.push_back(
907 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); 964 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer));
908 #else 965 #else
909 // No need to dup the imc_handle - we don't pass it anywhere else so 966 // No need to dup the imc_handle - we don't pass it anywhere else so
910 // it cannot be closed. 967 // it cannot be closed.
911 nacl::FileDescriptor imc_handle; 968 nacl::FileDescriptor imc_handle;
912 imc_handle.fd = internal_->sockets_for_renderer[i]; 969 imc_handle.fd = internal_->sockets_for_renderer[i];
913 imc_handle.auto_close = true; 970 imc_handle.auto_close = true;
914 handles_for_renderer.push_back(imc_handle); 971 handles_for_renderer.push_back(imc_handle);
915 #endif 972 #endif
916 } 973 }
917 974
918 const ChildProcessData& data = process_->GetData(); 975 const ChildProcessData& data = process_->GetData();
976 base::ProcessHandle nacl_process_handle;
919 #if defined(OS_WIN) 977 #if defined(OS_WIN)
920 // Copy the process handle into the renderer process. 978 // Copy the process handle into the renderer process.
921 if (!DuplicateHandle(base::GetCurrentProcessHandle(), 979 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
922 data.handle, 980 data.handle,
923 chrome_render_message_filter_->peer_handle(), 981 chrome_render_message_filter_->peer_handle(),
924 &nacl_process_handle, 982 &nacl_process_handle,
925 PROCESS_DUP_HANDLE, 983 PROCESS_DUP_HANDLE,
926 FALSE, 984 FALSE,
927 0)) { 985 0)) {
928 DLOG(ERROR) << "DuplicateHandle() failed"; 986 DLOG(ERROR) << "DuplicateHandle() failed";
929 return false; 987 return false;
930 } 988 }
931 #else 989 #else
932 // We use pid as process handle on Posix 990 // We use pid as process handle on Posix
933 nacl_process_handle = data.handle; 991 nacl_process_handle = data.handle;
934 #endif 992 #endif
935 993
936 // Get the pid of the NaCl process 994 // Get the pid of the NaCl process
937 base::ProcessId nacl_process_id = base::GetProcId(data.handle); 995 base::ProcessId nacl_process_id = base::GetProcId(data.handle);
938 996
939 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( 997 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
940 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); 998 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id);
941 chrome_render_message_filter_->Send(reply_msg_); 999 chrome_render_message_filter_->Send(reply_msg_);
942 chrome_render_message_filter_ = NULL; 1000 chrome_render_message_filter_ = NULL;
943 reply_msg_ = NULL; 1001 reply_msg_ = NULL;
944 internal_->sockets_for_renderer.clear(); 1002 internal_->sockets_for_renderer.clear();
1003 return true;
1004 }
945 1005
946 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; 1006 bool NaClProcessHost::SendStart() {
947 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { 1007 return ReplyToRenderer() && StartNaClExecution();
948 if (!SendHandleToSelLdr(data.handle,
949 internal_->sockets_for_sel_ldr[i], true,
950 &handles_for_sel_ldr)) {
951 return false;
952 }
953 }
954
955 // 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))
957 return false;
958
959 #if defined(OS_MACOSX)
960 // For dynamic loading support, NaCl requires a file descriptor that
961 // was created in /tmp, since those created with shm_open() are not
962 // mappable with PROT_EXEC. Rather than requiring an extra IPC
963 // round trip out of the sandbox, we create an FD here.
964 base::SharedMemory memory_buffer;
965 base::SharedMemoryCreateOptions options;
966 options.size = 1;
967 options.executable = true;
968 if (!memory_buffer.Create(options)) {
969 DLOG(ERROR) << "Failed to allocate memory buffer";
970 return false;
971 }
972 nacl::FileDescriptor memory_fd;
973 memory_fd.fd = dup(memory_buffer.handle().fd);
974 if (memory_fd.fd < 0) {
975 DLOG(ERROR) << "Failed to dup() a file descriptor";
976 return false;
977 }
978 memory_fd.auto_close = true;
979 handles_for_sel_ldr.push_back(memory_fd);
980 #endif
981
982 // Sending the version string over IPC avoids linkage issues in cases where
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 (debug_context_ != NULL) {
992 debug_context_->SetStartMessage(start_message);
993 debug_context_->SendStartMessage();
994 } else {
995 process_->Send(start_message);
996 }
997 #else
998 process_->Send(start_message);
999 #endif
1000
1001 internal_->sockets_for_sel_ldr.clear();
1002 return true;
1003 } 1008 }
1004 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 }
(...skipping 12 matching lines...) Expand all
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698