| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 | 6 |
| 7 #include "chrome/browser/nacl_host/nacl_process_host.h" | 7 #include "chrome/browser/nacl_host/nacl_process_host.h" |
| 8 | 8 |
| 9 #if defined(OS_POSIX) | 9 #if defined(OS_POSIX) |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/metrics/nacl_histogram.h" | 14 #include "base/metrics/nacl_histogram.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "chrome/browser/renderer_host/render_message_filter.h" | 16 #include "chrome/browser/renderer_host/render_message_filter.h" |
| 17 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" |
| 18 #include "chrome/common/logging_chrome.h" | 18 #include "chrome/common/logging_chrome.h" |
| 19 #include "chrome/common/nacl_cmd_line.h" | 19 #include "chrome/common/nacl_cmd_line.h" |
| 20 #include "chrome/common/nacl_messages.h" | 20 #include "chrome/common/nacl_messages.h" |
| 21 #include "chrome/common/render_messages.h" | 21 #include "chrome/common/render_messages.h" |
| 22 #include "ipc/ipc_switches.h" | 22 #include "ipc/ipc_switches.h" |
| 23 #include "native_client/src/shared/imc/nacl_imc.h" |
| 23 | 24 |
| 24 #if defined(OS_POSIX) | 25 #if defined(OS_POSIX) |
| 25 #include "ipc/ipc_channel_posix.h" | 26 #include "ipc/ipc_channel_posix.h" |
| 26 #elif defined(OS_WIN) | 27 #elif defined(OS_WIN) |
| 27 #include "chrome/browser/nacl_host/nacl_broker_service_win.h" | 28 #include "chrome/browser/nacl_host/nacl_broker_service_win.h" |
| 28 #endif | 29 #endif |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| 32 #if !defined(DISABLE_NACL) | 33 #if !defined(DISABLE_NACL) |
| 33 void SetCloseOnExec(nacl::Handle fd) { | 34 void SetCloseOnExec(nacl::Handle fd) { |
| 34 #if defined(OS_POSIX) | 35 #if defined(OS_POSIX) |
| 35 int flags = fcntl(fd, F_GETFD); | 36 int flags = fcntl(fd, F_GETFD); |
| 36 CHECK(flags != -1); | 37 CHECK(flags != -1); |
| 37 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | 38 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
| 38 CHECK(rc == 0); | 39 CHECK(rc == 0); |
| 39 #endif | 40 #endif |
| 40 } | 41 } |
| 41 #endif | 42 #endif |
| 42 | 43 |
| 43 } // namespace | 44 } // namespace |
| 44 | 45 |
| 46 struct NaClProcessHost::NaClInternal { |
| 47 std::vector<nacl::Handle> sockets_for_renderer; |
| 48 std::vector<nacl::Handle> sockets_for_sel_ldr; |
| 49 }; |
| 50 |
| 45 NaClProcessHost::NaClProcessHost( | 51 NaClProcessHost::NaClProcessHost( |
| 46 ResourceDispatcherHost *resource_dispatcher_host, | 52 ResourceDispatcherHost *resource_dispatcher_host, |
| 47 const std::wstring& url) | 53 const std::wstring& url) |
| 48 : BrowserChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host), | 54 : BrowserChildProcessHost(NACL_LOADER_PROCESS, resource_dispatcher_host), |
| 49 resource_dispatcher_host_(resource_dispatcher_host), | 55 resource_dispatcher_host_(resource_dispatcher_host), |
| 50 reply_msg_(NULL), | 56 reply_msg_(NULL), |
| 57 internal_(new NaClInternal()), |
| 51 running_on_wow64_(false) { | 58 running_on_wow64_(false) { |
| 52 set_name(url); | 59 set_name(url); |
| 53 #if defined(OS_WIN) | 60 #if defined(OS_WIN) |
| 54 CheckIsWow64(); | 61 CheckIsWow64(); |
| 55 #endif | 62 #endif |
| 56 } | 63 } |
| 57 | 64 |
| 58 NaClProcessHost::~NaClProcessHost() { | 65 NaClProcessHost::~NaClProcessHost() { |
| 59 if (!reply_msg_) | 66 if (!reply_msg_) |
| 60 return; | 67 return; |
| 61 | 68 |
| 62 // nacl::Close() is not available at link time if DISABLE_NACL is | 69 // nacl::Close() is not available at link time if DISABLE_NACL is |
| 63 // defined, but we still compile a bunch of other code from this | 70 // defined, but we still compile a bunch of other code from this |
| 64 // file anyway. TODO(mseaborn): Make this less messy. | 71 // file anyway. TODO(mseaborn): Make this less messy. |
| 65 #ifndef DISABLE_NACL | 72 #ifndef DISABLE_NACL |
| 66 for (size_t i = 0; i < sockets_for_renderer_.size(); i++) { | 73 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
| 67 nacl::Close(sockets_for_renderer_[i]); | 74 nacl::Close(internal_->sockets_for_renderer[i]); |
| 68 } | 75 } |
| 69 for (size_t i = 0; i < sockets_for_sel_ldr_.size(); i++) { | 76 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
| 70 nacl::Close(sockets_for_sel_ldr_[i]); | 77 nacl::Close(internal_->sockets_for_sel_ldr[i]); |
| 71 } | 78 } |
| 72 #endif | 79 #endif |
| 73 | 80 |
| 74 // OnProcessLaunched didn't get called because the process couldn't launch. | 81 // OnProcessLaunched didn't get called because the process couldn't launch. |
| 75 // Don't keep the renderer hanging. | 82 // Don't keep the renderer hanging. |
| 76 reply_msg_->set_reply_error(); | 83 reply_msg_->set_reply_error(); |
| 77 render_message_filter_->Send(reply_msg_); | 84 render_message_filter_->Send(reply_msg_); |
| 78 } | 85 } |
| 79 | 86 |
| 80 bool NaClProcessHost::Launch(RenderMessageFilter* render_message_filter, | 87 bool NaClProcessHost::Launch(RenderMessageFilter* render_message_filter, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 98 // This is mainly for the benefit of Windows, where sockets cannot | 105 // This is mainly for the benefit of Windows, where sockets cannot |
| 99 // be passed in messages, but are copied via DuplicateHandle(). | 106 // be passed in messages, but are copied via DuplicateHandle(). |
| 100 // This means the sandboxed renderer cannot send handles to the | 107 // This means the sandboxed renderer cannot send handles to the |
| 101 // browser process. | 108 // browser process. |
| 102 | 109 |
| 103 for (int i = 0; i < socket_count; i++) { | 110 for (int i = 0; i < socket_count; i++) { |
| 104 nacl::Handle pair[2]; | 111 nacl::Handle pair[2]; |
| 105 // Create a connected socket | 112 // Create a connected socket |
| 106 if (nacl::SocketPair(pair) == -1) | 113 if (nacl::SocketPair(pair) == -1) |
| 107 return false; | 114 return false; |
| 108 sockets_for_renderer_.push_back(pair[0]); | 115 internal_->sockets_for_renderer.push_back(pair[0]); |
| 109 sockets_for_sel_ldr_.push_back(pair[1]); | 116 internal_->sockets_for_sel_ldr.push_back(pair[1]); |
| 110 SetCloseOnExec(pair[0]); | 117 SetCloseOnExec(pair[0]); |
| 111 SetCloseOnExec(pair[1]); | 118 SetCloseOnExec(pair[1]); |
| 112 } | 119 } |
| 113 | 120 |
| 114 // Launch the process | 121 // Launch the process |
| 115 if (!LaunchSelLdr()) { | 122 if (!LaunchSelLdr()) { |
| 116 return false; | 123 return false; |
| 117 } | 124 } |
| 118 UmaNaclHistogramEnumeration(NACL_STARTED); | 125 UmaNaclHistogramEnumeration(NACL_STARTED); |
| 119 render_message_filter_ = render_message_filter; | 126 render_message_filter_ = render_message_filter; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 #if defined(OS_WIN) | 183 #if defined(OS_WIN) |
| 177 NaClBrokerService::GetInstance()->OnLoaderDied(); | 184 NaClBrokerService::GetInstance()->OnLoaderDied(); |
| 178 #endif | 185 #endif |
| 179 BrowserChildProcessHost::OnChildDied(); | 186 BrowserChildProcessHost::OnChildDied(); |
| 180 } | 187 } |
| 181 | 188 |
| 182 void NaClProcessHost::OnProcessLaunched() { | 189 void NaClProcessHost::OnProcessLaunched() { |
| 183 std::vector<nacl::FileDescriptor> handles_for_renderer; | 190 std::vector<nacl::FileDescriptor> handles_for_renderer; |
| 184 base::ProcessHandle nacl_process_handle; | 191 base::ProcessHandle nacl_process_handle; |
| 185 | 192 |
| 186 for (size_t i = 0; i < sockets_for_renderer_.size(); i++) { | 193 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { |
| 187 #if defined(OS_WIN) | 194 #if defined(OS_WIN) |
| 188 // Copy the handle into the renderer process. | 195 // Copy the handle into the renderer process. |
| 189 HANDLE handle_in_renderer; | 196 HANDLE handle_in_renderer; |
| 190 DuplicateHandle(base::GetCurrentProcessHandle(), | 197 DuplicateHandle(base::GetCurrentProcessHandle(), |
| 191 reinterpret_cast<HANDLE>(sockets_for_renderer_[i]), | 198 reinterpret_cast<HANDLE>( |
| 199 internal_->sockets_for_renderer[i]), |
| 192 render_message_filter_->peer_handle(), | 200 render_message_filter_->peer_handle(), |
| 193 &handle_in_renderer, | 201 &handle_in_renderer, |
| 194 GENERIC_READ | GENERIC_WRITE, | 202 GENERIC_READ | GENERIC_WRITE, |
| 195 FALSE, | 203 FALSE, |
| 196 DUPLICATE_CLOSE_SOURCE); | 204 DUPLICATE_CLOSE_SOURCE); |
| 197 handles_for_renderer.push_back( | 205 handles_for_renderer.push_back( |
| 198 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); | 206 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); |
| 199 #else | 207 #else |
| 200 // No need to dup the imc_handle - we don't pass it anywhere else so | 208 // No need to dup the imc_handle - we don't pass it anywhere else so |
| 201 // it cannot be closed. | 209 // it cannot be closed. |
| 202 nacl::FileDescriptor imc_handle; | 210 nacl::FileDescriptor imc_handle; |
| 203 imc_handle.fd = sockets_for_renderer_[i]; | 211 imc_handle.fd = internal_->sockets_for_renderer[i]; |
| 204 imc_handle.auto_close = true; | 212 imc_handle.auto_close = true; |
| 205 handles_for_renderer.push_back(imc_handle); | 213 handles_for_renderer.push_back(imc_handle); |
| 206 #endif | 214 #endif |
| 207 } | 215 } |
| 208 | 216 |
| 209 #if defined(OS_WIN) | 217 #if defined(OS_WIN) |
| 210 // Copy the process handle into the renderer process. | 218 // Copy the process handle into the renderer process. |
| 211 DuplicateHandle(base::GetCurrentProcessHandle(), | 219 DuplicateHandle(base::GetCurrentProcessHandle(), |
| 212 handle(), | 220 handle(), |
| 213 render_message_filter_->peer_handle(), | 221 render_message_filter_->peer_handle(), |
| 214 &nacl_process_handle, | 222 &nacl_process_handle, |
| 215 PROCESS_DUP_HANDLE, | 223 PROCESS_DUP_HANDLE, |
| 216 FALSE, | 224 FALSE, |
| 217 0); | 225 0); |
| 218 #else | 226 #else |
| 219 // We use pid as process handle on Posix | 227 // We use pid as process handle on Posix |
| 220 nacl_process_handle = handle(); | 228 nacl_process_handle = handle(); |
| 221 #endif | 229 #endif |
| 222 | 230 |
| 223 // Get the pid of the NaCl process | 231 // Get the pid of the NaCl process |
| 224 base::ProcessId nacl_process_id = base::GetProcId(handle()); | 232 base::ProcessId nacl_process_id = base::GetProcId(handle()); |
| 225 | 233 |
| 226 ViewHostMsg_LaunchNaCl::WriteReplyParams( | 234 ViewHostMsg_LaunchNaCl::WriteReplyParams( |
| 227 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); | 235 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); |
| 228 render_message_filter_->Send(reply_msg_); | 236 render_message_filter_->Send(reply_msg_); |
| 229 render_message_filter_ = NULL; | 237 render_message_filter_ = NULL; |
| 230 reply_msg_ = NULL; | 238 reply_msg_ = NULL; |
| 231 sockets_for_renderer_.clear(); | 239 internal_->sockets_for_renderer.clear(); |
| 232 | 240 |
| 233 SendStartMessage(); | 241 SendStartMessage(); |
| 234 } | 242 } |
| 235 | 243 |
| 236 void NaClProcessHost::SendStartMessage() { | 244 void NaClProcessHost::SendStartMessage() { |
| 237 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; | 245 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; |
| 238 for (size_t i = 0; i < sockets_for_sel_ldr_.size(); i++) { | 246 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { |
| 239 #if defined(OS_WIN) | 247 #if defined(OS_WIN) |
| 240 HANDLE channel; | 248 HANDLE channel; |
| 241 if (!DuplicateHandle(GetCurrentProcess(), | 249 if (!DuplicateHandle(GetCurrentProcess(), |
| 242 reinterpret_cast<HANDLE>(sockets_for_sel_ldr_[i]), | 250 reinterpret_cast<HANDLE>( |
| 251 internal_->sockets_for_sel_ldr[i]), |
| 243 handle(), | 252 handle(), |
| 244 &channel, | 253 &channel, |
| 245 GENERIC_READ | GENERIC_WRITE, | 254 GENERIC_READ | GENERIC_WRITE, |
| 246 FALSE, DUPLICATE_CLOSE_SOURCE)) { | 255 FALSE, DUPLICATE_CLOSE_SOURCE)) { |
| 247 return; | 256 return; |
| 248 } | 257 } |
| 249 handles_for_sel_ldr.push_back( | 258 handles_for_sel_ldr.push_back( |
| 250 reinterpret_cast<nacl::FileDescriptor>(channel)); | 259 reinterpret_cast<nacl::FileDescriptor>(channel)); |
| 251 #else | 260 #else |
| 252 nacl::FileDescriptor channel; | 261 nacl::FileDescriptor channel; |
| 253 channel.fd = dup(sockets_for_sel_ldr_[i]); | 262 channel.fd = dup(internal_->sockets_for_sel_ldr[i]); |
| 254 if (channel.fd < 0) { | 263 if (channel.fd < 0) { |
| 255 LOG(ERROR) << "Failed to dup() a file descriptor"; | 264 LOG(ERROR) << "Failed to dup() a file descriptor"; |
| 256 return; | 265 return; |
| 257 } | 266 } |
| 258 channel.auto_close = true; | 267 channel.auto_close = true; |
| 259 handles_for_sel_ldr.push_back(channel); | 268 handles_for_sel_ldr.push_back(channel); |
| 260 #endif | 269 #endif |
| 261 } | 270 } |
| 262 | 271 |
| 263 #if defined(OS_MACOSX) | 272 #if defined(OS_MACOSX) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 274 memory_fd.fd = dup(memory_buffer.handle().fd); | 283 memory_fd.fd = dup(memory_buffer.handle().fd); |
| 275 if (memory_fd.fd < 0) { | 284 if (memory_fd.fd < 0) { |
| 276 LOG(ERROR) << "Failed to dup() a file descriptor"; | 285 LOG(ERROR) << "Failed to dup() a file descriptor"; |
| 277 return; | 286 return; |
| 278 } | 287 } |
| 279 memory_fd.auto_close = true; | 288 memory_fd.auto_close = true; |
| 280 handles_for_sel_ldr.push_back(memory_fd); | 289 handles_for_sel_ldr.push_back(memory_fd); |
| 281 #endif | 290 #endif |
| 282 | 291 |
| 283 Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); | 292 Send(new NaClProcessMsg_Start(handles_for_sel_ldr)); |
| 284 sockets_for_sel_ldr_.clear(); | 293 internal_->sockets_for_sel_ldr.clear(); |
| 285 } | 294 } |
| 286 | 295 |
| 287 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { | 296 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { |
| 288 NOTREACHED() << "Invalid message with type = " << msg.type(); | 297 NOTREACHED() << "Invalid message with type = " << msg.type(); |
| 289 return false; | 298 return false; |
| 290 } | 299 } |
| 291 | 300 |
| 292 bool NaClProcessHost::CanShutdown() { | 301 bool NaClProcessHost::CanShutdown() { |
| 293 return true; | 302 return true; |
| 294 } | 303 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 306 if (fnIsWow64Process != NULL) { | 315 if (fnIsWow64Process != NULL) { |
| 307 BOOL bIsWow64 = FALSE; | 316 BOOL bIsWow64 = FALSE; |
| 308 if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { | 317 if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { |
| 309 if (bIsWow64) { | 318 if (bIsWow64) { |
| 310 running_on_wow64_ = true; | 319 running_on_wow64_ = true; |
| 311 } | 320 } |
| 312 } | 321 } |
| 313 } | 322 } |
| 314 } | 323 } |
| 315 #endif | 324 #endif |
| OLD | NEW |