| 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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 }; | 228 }; |
| 229 | 229 |
| 230 #if defined(OS_WIN) | 230 #if defined(OS_WIN) |
| 231 static bool RunningOnWOW64() { | 231 static bool RunningOnWOW64() { |
| 232 return (base::win::OSInfo::GetInstance()->wow64_status() == | 232 return (base::win::OSInfo::GetInstance()->wow64_status() == |
| 233 base::win::OSInfo::WOW64_ENABLED); | 233 base::win::OSInfo::WOW64_ENABLED); |
| 234 } | 234 } |
| 235 #endif | 235 #endif |
| 236 | 236 |
| 237 NaClProcessHost::NaClProcessHost(const std::wstring& url) | 237 NaClProcessHost::NaClProcessHost(const std::wstring& url) |
| 238 : reply_msg_(NULL), | 238 : |
| 239 #if defined(OS_WIN) |
| 240 process_launched_by_broker_(false), |
| 241 #endif |
| 242 reply_msg_(NULL), |
| 239 internal_(new NaClInternal()), | 243 internal_(new NaClInternal()), |
| 240 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 244 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 241 enable_exception_handling_(false) { | 245 enable_exception_handling_(false) { |
| 242 process_.reset(content::BrowserChildProcessHost::Create( | 246 process_.reset(content::BrowserChildProcessHost::Create( |
| 243 content::PROCESS_TYPE_NACL_LOADER, this)); | 247 content::PROCESS_TYPE_NACL_LOADER, this)); |
| 244 process_->SetName(WideToUTF16Hack(url)); | 248 process_->SetName(WideToUTF16Hack(url)); |
| 245 | 249 |
| 246 // We allow untrusted hardware exception handling to be enabled via | 250 // We allow untrusted hardware exception handling to be enabled via |
| 247 // an env var for consistency with the standalone build of NaCl. | 251 // an env var for consistency with the standalone build of NaCl. |
| 248 if (CommandLine::ForCurrentProcess()->HasSwitch( | 252 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 } | 284 } |
| 281 } | 285 } |
| 282 | 286 |
| 283 if (reply_msg_) { | 287 if (reply_msg_) { |
| 284 // The process failed to launch for some reason. | 288 // The process failed to launch for some reason. |
| 285 // Don't keep the renderer hanging. | 289 // Don't keep the renderer hanging. |
| 286 reply_msg_->set_reply_error(); | 290 reply_msg_->set_reply_error(); |
| 287 chrome_render_message_filter_->Send(reply_msg_); | 291 chrome_render_message_filter_->Send(reply_msg_); |
| 288 } | 292 } |
| 289 #if defined(OS_WIN) | 293 #if defined(OS_WIN) |
| 290 if (RunningOnWOW64()) { | 294 if (process_launched_by_broker_) { |
| 291 // If the nacl-gdb switch is not empty, the NaCl loader has been launched | 295 NaClBrokerService::GetInstance()->OnLoaderDied(); |
| 292 // without the broker and so we shouldn't inform the broker about | |
| 293 // the loader termination. | |
| 294 if (CommandLine::ForCurrentProcess()->GetSwitchValuePath( | |
| 295 switches::kNaClGdb).empty()) { | |
| 296 NaClBrokerService::GetInstance()->OnLoaderDied(); | |
| 297 } | |
| 298 } | 296 } |
| 299 if (debug_context_ != NULL) { | 297 if (debug_context_ != NULL) { |
| 300 debug_context_->SetChildProcessHost(NULL); | 298 debug_context_->SetChildProcessHost(NULL); |
| 301 } | 299 } |
| 302 #endif | 300 #endif |
| 303 } | 301 } |
| 304 | 302 |
| 305 // Attempt to ensure the IRT will be available when we need it, but don't wait. | 303 // Attempt to ensure the IRT will be available when we need it, but don't wait. |
| 306 bool NaClBrowser::EnsureIrtAvailable() { | 304 bool NaClBrowser::EnsureIrtAvailable() { |
| 307 if (IrtAvailable()) | 305 if (IrtAvailable()) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 323 // This is called at browser startup. | 321 // This is called at browser startup. |
| 324 // static | 322 // static |
| 325 void NaClProcessHost::EarlyStartup() { | 323 void NaClProcessHost::EarlyStartup() { |
| 326 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 324 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 327 // Open the IRT file early to make sure that it isn't replaced out from | 325 // Open the IRT file early to make sure that it isn't replaced out from |
| 328 // under us by autoupdate. | 326 // under us by autoupdate. |
| 329 NaClBrowser::GetInstance()->EnsureIrtAvailable(); | 327 NaClBrowser::GetInstance()->EnsureIrtAvailable(); |
| 330 #endif | 328 #endif |
| 331 } | 329 } |
| 332 | 330 |
| 333 bool NaClProcessHost::Launch( | 331 void NaClProcessHost::Launch( |
| 334 ChromeRenderMessageFilter* chrome_render_message_filter, | 332 ChromeRenderMessageFilter* chrome_render_message_filter, |
| 335 int socket_count, | 333 int socket_count, |
| 336 IPC::Message* reply_msg) { | 334 IPC::Message* reply_msg) { |
| 335 chrome_render_message_filter_ = chrome_render_message_filter; |
| 336 reply_msg_ = reply_msg; |
| 337 |
| 337 // Place an arbitrary limit on the number of sockets to limit | 338 // Place an arbitrary limit on the number of sockets to limit |
| 338 // exposure in case the renderer is compromised. We can increase | 339 // exposure in case the renderer is compromised. We can increase |
| 339 // this if necessary. | 340 // this if necessary. |
| 340 if (socket_count > 8) { | 341 if (socket_count > 8) { |
| 341 return false; | 342 delete this; |
| 343 return; |
| 342 } | 344 } |
| 343 | 345 |
| 344 // Start getting the IRT open asynchronously while we launch the NaCl process. | 346 // Start getting the IRT open asynchronously while we launch the NaCl process. |
| 345 // We'll make sure this actually finished in OnProcessLaunched, below. | 347 // We'll make sure this actually finished in OnProcessLaunched, below. |
| 346 if (!NaClBrowser::GetInstance()->EnsureIrtAvailable()) { | 348 if (!NaClBrowser::GetInstance()->EnsureIrtAvailable()) { |
| 347 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed"; | 349 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed"; |
| 348 return false; | 350 delete this; |
| 351 return; |
| 349 } | 352 } |
| 350 | 353 |
| 351 // Rather than creating a socket pair in the renderer, and passing | 354 // Rather than creating a socket pair in the renderer, and passing |
| 352 // one side through the browser to sel_ldr, socket pairs are created | 355 // one side through the browser to sel_ldr, socket pairs are created |
| 353 // in the browser and then passed to the renderer and sel_ldr. | 356 // in the browser and then passed to the renderer and sel_ldr. |
| 354 // | 357 // |
| 355 // This is mainly for the benefit of Windows, where sockets cannot | 358 // This is mainly for the benefit of Windows, where sockets cannot |
| 356 // be passed in messages, but are copied via DuplicateHandle(). | 359 // be passed in messages, but are copied via DuplicateHandle(). |
| 357 // This means the sandboxed renderer cannot send handles to the | 360 // This means the sandboxed renderer cannot send handles to the |
| 358 // browser process. | 361 // browser process. |
| 359 | 362 |
| 360 for (int i = 0; i < socket_count; i++) { | 363 for (int i = 0; i < socket_count; i++) { |
| 361 nacl::Handle pair[2]; | 364 nacl::Handle pair[2]; |
| 362 // Create a connected socket | 365 // Create a connected socket |
| 363 if (nacl::SocketPair(pair) == -1) | 366 if (nacl::SocketPair(pair) == -1) { |
| 364 return false; | 367 delete this; |
| 368 return; |
| 369 } |
| 365 internal_->sockets_for_renderer.push_back(pair[0]); | 370 internal_->sockets_for_renderer.push_back(pair[0]); |
| 366 internal_->sockets_for_sel_ldr.push_back(pair[1]); | 371 internal_->sockets_for_sel_ldr.push_back(pair[1]); |
| 367 SetCloseOnExec(pair[0]); | 372 SetCloseOnExec(pair[0]); |
| 368 SetCloseOnExec(pair[1]); | 373 SetCloseOnExec(pair[1]); |
| 369 } | 374 } |
| 370 | 375 |
| 371 // Launch the process | 376 // Launch the process |
| 372 if (!LaunchSelLdr()) { | 377 if (!LaunchSelLdr()) { |
| 373 return false; | 378 delete this; |
| 374 } | 379 } |
| 375 | |
| 376 chrome_render_message_filter_ = chrome_render_message_filter; | |
| 377 | |
| 378 // On success, we take responsibility for sending the reply. | |
| 379 reply_msg_ = reply_msg; | |
| 380 return true; | |
| 381 } | 380 } |
| 382 | 381 |
| 383 scoped_ptr<CommandLine> NaClProcessHost::LaunchWithNaClGdb( | 382 scoped_ptr<CommandLine> NaClProcessHost::LaunchWithNaClGdb( |
| 384 const FilePath& nacl_gdb, CommandLine* line) { | 383 const FilePath& nacl_gdb, CommandLine* line) { |
| 385 CommandLine* cmd_line = new CommandLine(nacl_gdb); | 384 CommandLine* cmd_line = new CommandLine(nacl_gdb); |
| 386 // We can't use PrependWrapper because our parameters contain spaces. | 385 // We can't use PrependWrapper because our parameters contain spaces. |
| 387 cmd_line->AppendArg("--eval-command"); | 386 cmd_line->AppendArg("--eval-command"); |
| 388 const FilePath::StringType& irt_path = | 387 const FilePath::StringType& irt_path = |
| 389 NaClBrowser::GetInstance()->GetIrtFilePath().value(); | 388 NaClBrowser::GetInstance()->GetIrtFilePath().value(); |
| 390 cmd_line->AppendArgNative(FILE_PATH_LITERAL("nacl-irt ") + irt_path); | 389 cmd_line->AppendArgNative(FILE_PATH_LITERAL("nacl-irt ") + irt_path); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 #elif defined(OS_POSIX) | 477 #elif defined(OS_POSIX) |
| 479 process_->Launch(nacl_loader_prefix.empty(), // use_zygote | 478 process_->Launch(nacl_loader_prefix.empty(), // use_zygote |
| 480 base::EnvironmentVector(), | 479 base::EnvironmentVector(), |
| 481 cmd_line.release()); | 480 cmd_line.release()); |
| 482 #endif | 481 #endif |
| 483 | 482 |
| 484 return true; | 483 return true; |
| 485 } | 484 } |
| 486 | 485 |
| 487 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { | 486 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { |
| 487 #if defined(OS_WIN) |
| 488 process_launched_by_broker_ = true; |
| 489 #endif |
| 488 process_->SetHandle(handle); | 490 process_->SetHandle(handle); |
| 489 OnProcessLaunched(); | 491 OnProcessLaunched(); |
| 490 } | 492 } |
| 491 | 493 |
| 492 void NaClProcessHost::OnProcessCrashed(int exit_code) { | 494 void NaClProcessHost::OnProcessCrashed(int exit_code) { |
| 493 std::string message = base::StringPrintf( | 495 std::string message = base::StringPrintf( |
| 494 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); | 496 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); |
| 495 LOG(ERROR) << message; | 497 LOG(ERROR) << message; |
| 496 } | 498 } |
| 497 | 499 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 process_->Send(start_message); | 810 process_->Send(start_message); |
| 809 #endif | 811 #endif |
| 810 | 812 |
| 811 internal_->sockets_for_sel_ldr.clear(); | 813 internal_->sockets_for_sel_ldr.clear(); |
| 812 } | 814 } |
| 813 | 815 |
| 814 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { | 816 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { |
| 815 NOTREACHED() << "Invalid message with type = " << msg.type(); | 817 NOTREACHED() << "Invalid message with type = " << msg.type(); |
| 816 return false; | 818 return false; |
| 817 } | 819 } |
| OLD | NEW |