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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 int flags = DUPLICATE_SAME_ACCESS; | 95 int flags = DUPLICATE_SAME_ACCESS; |
| 96 if (close_source) | 96 if (close_source) |
| 97 flags |= DUPLICATE_CLOSE_SOURCE; | 97 flags |= DUPLICATE_CLOSE_SOURCE; |
| 98 if (!DuplicateHandle(GetCurrentProcess(), | 98 if (!DuplicateHandle(GetCurrentProcess(), |
| 99 reinterpret_cast<HANDLE>(sourceh), | 99 reinterpret_cast<HANDLE>(sourceh), |
| 100 processh, | 100 processh, |
| 101 &channel, | 101 &channel, |
| 102 0, // Unused given DUPLICATE_SAME_ACCESS. | 102 0, // Unused given DUPLICATE_SAME_ACCESS. |
| 103 FALSE, | 103 FALSE, |
| 104 flags)) { | 104 flags)) { |
| 105 DLOG(ERROR) << "DuplicateHandle() failed"; | 105 LOG(ERROR) << "DuplicateHandle() failed"; |
| 106 return false; | 106 return false; |
| 107 } | 107 } |
| 108 handles_for_sel_ldr->push_back( | 108 handles_for_sel_ldr->push_back( |
| 109 reinterpret_cast<nacl::FileDescriptor>(channel)); | 109 reinterpret_cast<nacl::FileDescriptor>(channel)); |
| 110 #else | 110 #else |
| 111 nacl::FileDescriptor channel; | 111 nacl::FileDescriptor channel; |
| 112 channel.fd = sourceh; | 112 channel.fd = sourceh; |
| 113 channel.auto_close = close_source; | 113 channel.auto_close = close_source; |
| 114 handles_for_sel_ldr->push_back(channel); | 114 handles_for_sel_ldr->push_back(channel); |
| 115 #endif | 115 #endif |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 263 scoped_refptr<ExtensionInfoMap> extension_info_map) { | 263 scoped_refptr<ExtensionInfoMap> extension_info_map) { |
| 264 chrome_render_message_filter_ = chrome_render_message_filter; | 264 chrome_render_message_filter_ = chrome_render_message_filter; |
| 265 reply_msg_ = reply_msg; | 265 reply_msg_ = reply_msg; |
| 266 extension_info_map_ = extension_info_map; | 266 extension_info_map_ = extension_info_map; |
| 267 | 267 |
| 268 // Start getting the IRT open asynchronously while we launch the NaCl process. | 268 // Start getting the IRT open asynchronously while we launch the NaCl process. |
| 269 // We'll make sure this actually finished in StartWithLaunchedProcess, below. | 269 // We'll make sure this actually finished in StartWithLaunchedProcess, below. |
| 270 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 270 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 271 nacl_browser->EnsureAllResourcesAvailable(); | 271 nacl_browser->EnsureAllResourcesAvailable(); |
| 272 if (!nacl_browser->IsOk()) { | 272 if (!nacl_browser->IsOk()) { |
| 273 DLOG(ERROR) << "Cannot launch NaCl process"; | 273 LOG(ERROR) << "NaCl process launch failed: could not find all the " |
| 274 "resources needed to launch the process."; | |
|
Mark Seaborn
2013/01/16 00:27:54
This is being picky, but most log messages in Chro
Nick Bray (chromium)
2013/01/16 05:54:52
Done.
| |
| 274 delete this; | 275 delete this; |
| 275 return; | 276 return; |
| 276 } | 277 } |
| 277 | 278 |
| 278 // Rather than creating a socket pair in the renderer, and passing | 279 // Rather than creating a socket pair in the renderer, and passing |
| 279 // one side through the browser to sel_ldr, socket pairs are created | 280 // one side through the browser to sel_ldr, socket pairs are created |
| 280 // in the browser and then passed to the renderer and sel_ldr. | 281 // in the browser and then passed to the renderer and sel_ldr. |
| 281 // | 282 // |
| 282 // This is mainly for the benefit of Windows, where sockets cannot | 283 // This is mainly for the benefit of Windows, where sockets cannot |
| 283 // be passed in messages, but are copied via DuplicateHandle(). | 284 // be passed in messages, but are copied via DuplicateHandle(). |
| 284 // This means the sandboxed renderer cannot send handles to the | 285 // This means the sandboxed renderer cannot send handles to the |
| 285 // browser process. | 286 // browser process. |
| 286 | 287 |
| 287 nacl::Handle pair[2]; | 288 nacl::Handle pair[2]; |
| 288 // Create a connected socket | 289 // Create a connected socket |
| 289 if (nacl::SocketPair(pair) == -1) { | 290 if (nacl::SocketPair(pair) == -1) { |
| 291 LOG(ERROR) << "NaCl process launch failed: could not create a socket pair."; | |
| 290 delete this; | 292 delete this; |
| 291 return; | 293 return; |
| 292 } | 294 } |
| 293 internal_->socket_for_renderer = pair[0]; | 295 internal_->socket_for_renderer = pair[0]; |
| 294 internal_->socket_for_sel_ldr = pair[1]; | 296 internal_->socket_for_sel_ldr = pair[1]; |
| 295 SetCloseOnExec(pair[0]); | 297 SetCloseOnExec(pair[0]); |
| 296 SetCloseOnExec(pair[1]); | 298 SetCloseOnExec(pair[1]); |
| 297 | 299 |
| 298 // Launch the process | 300 // Launch the process |
| 299 if (!LaunchSelLdr()) { | 301 if (!LaunchSelLdr()) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 314 base::kProcessAccessDuplicateHandle | | 316 base::kProcessAccessDuplicateHandle | |
| 315 base::kProcessAccessQueryInformation | | 317 base::kProcessAccessQueryInformation | |
| 316 base::kProcessAccessWaitForTermination, | 318 base::kProcessAccessWaitForTermination, |
| 317 &process)) { | 319 &process)) { |
| 318 process_->SetHandle(process); | 320 process_->SetHandle(process); |
| 319 if (!StartWithLaunchedProcess()) { | 321 if (!StartWithLaunchedProcess()) { |
| 320 delete this; | 322 delete this; |
| 321 return; | 323 return; |
| 322 } | 324 } |
| 323 } else { | 325 } else { |
| 324 DLOG(ERROR) << "Failed to get process handle"; | 326 LOG(ERROR) << "Failed to get process handle"; |
| 325 } | 327 } |
| 326 } | 328 } |
| 327 } | 329 } |
| 328 #else | 330 #else |
| 329 void NaClProcessHost::OnChannelConnected(int32 peer_pid) { | 331 void NaClProcessHost::OnChannelConnected(int32 peer_pid) { |
| 330 } | 332 } |
| 331 #endif | 333 #endif |
| 332 | 334 |
| 333 #if defined(OS_WIN) | 335 #if defined(OS_WIN) |
| 334 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { | 336 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 manifest_url_.SchemeIs(extensions::kExtensionScheme)) { | 485 manifest_url_.SchemeIs(extensions::kExtensionScheme)) { |
| 484 std::string path = manifest_url_.path(); | 486 std::string path = manifest_url_.path(); |
| 485 TrimString(path, "/", &path); // Remove first slash | 487 TrimString(path, "/", &path); // Remove first slash |
| 486 return extension->path().AppendASCII(path); | 488 return extension->path().AppendASCII(path); |
| 487 } | 489 } |
| 488 return FilePath(); | 490 return FilePath(); |
| 489 } | 491 } |
| 490 | 492 |
| 491 bool NaClProcessHost::LaunchSelLdr() { | 493 bool NaClProcessHost::LaunchSelLdr() { |
| 492 std::string channel_id = process_->GetHost()->CreateChannel(); | 494 std::string channel_id = process_->GetHost()->CreateChannel(); |
| 493 if (channel_id.empty()) | 495 if (channel_id.empty()) { |
| 496 LOG(ERROR) << "NaCl process launch failed: could not create channel."; | |
| 494 return false; | 497 return false; |
| 498 } | |
| 495 | 499 |
| 496 CommandLine::StringType nacl_loader_prefix; | 500 CommandLine::StringType nacl_loader_prefix; |
| 497 #if defined(OS_POSIX) | 501 #if defined(OS_POSIX) |
| 498 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative( | 502 nacl_loader_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueNative( |
| 499 switches::kNaClLoaderCmdPrefix); | 503 switches::kNaClLoaderCmdPrefix); |
| 500 #endif // defined(OS_POSIX) | 504 #endif // defined(OS_POSIX) |
| 501 | 505 |
| 502 // Build command line for nacl. | 506 // Build command line for nacl. |
| 503 | 507 |
| 504 #if defined(OS_MACOSX) | 508 #if defined(OS_MACOSX) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 517 #endif | 521 #endif |
| 518 | 522 |
| 519 FilePath exe_path = ChildProcessHost::GetChildPath(flags); | 523 FilePath exe_path = ChildProcessHost::GetChildPath(flags); |
| 520 if (exe_path.empty()) | 524 if (exe_path.empty()) |
| 521 return false; | 525 return false; |
| 522 | 526 |
| 523 #if defined(OS_WIN) | 527 #if defined(OS_WIN) |
| 524 // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe | 528 // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe |
| 525 if (RunningOnWOW64()) { | 529 if (RunningOnWOW64()) { |
| 526 FilePath module_path; | 530 FilePath module_path; |
| 527 if (!PathService::Get(base::FILE_MODULE, &module_path)) | 531 if (!PathService::Get(base::FILE_MODULE, &module_path)) { |
| 532 LOG(ERROR) << "NaCl process launch failed: could not resolve module."; | |
| 528 return false; | 533 return false; |
| 534 } | |
| 529 exe_path = module_path.DirName().Append(chrome::kNaClAppName); | 535 exe_path = module_path.DirName().Append(chrome::kNaClAppName); |
| 530 } | 536 } |
| 531 #endif | 537 #endif |
| 532 | 538 |
| 533 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path)); | 539 scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path)); |
| 534 nacl::CopyNaClCommandLineArguments(cmd_line.get()); | 540 nacl::CopyNaClCommandLineArguments(cmd_line.get()); |
| 535 | 541 |
| 536 cmd_line->AppendSwitchASCII(switches::kProcessType, | 542 cmd_line->AppendSwitchASCII(switches::kProcessType, |
| 537 switches::kNaClLoaderProcess); | 543 switches::kNaClLoaderProcess); |
| 538 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); | 544 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 559 // call OnProcessLaunched. | 565 // call OnProcessLaunched. |
| 560 return base::LaunchProcess(*gdb_cmd_line, base::LaunchOptions(), NULL); | 566 return base::LaunchProcess(*gdb_cmd_line, base::LaunchOptions(), NULL); |
| 561 #elif defined(OS_LINUX) | 567 #elif defined(OS_LINUX) |
| 562 wait_for_nacl_gdb_ = true; | 568 wait_for_nacl_gdb_ = true; |
| 563 #endif | 569 #endif |
| 564 } | 570 } |
| 565 | 571 |
| 566 // On Windows we might need to start the broker process to launch a new loader | 572 // On Windows we might need to start the broker process to launch a new loader |
| 567 #if defined(OS_WIN) | 573 #if defined(OS_WIN) |
| 568 if (RunningOnWOW64()) { | 574 if (RunningOnWOW64()) { |
| 569 return NaClBrokerService::GetInstance()->LaunchLoader( | 575 if (!NaClBrokerService::GetInstance()->LaunchLoader( |
| 570 weak_factory_.GetWeakPtr(), channel_id); | 576 weak_factory_.GetWeakPtr(), channel_id)) { |
|
Mark Seaborn
2013/01/16 00:27:54
Indent function argument
Nick Bray (chromium)
2013/01/16 05:54:52
How? This is technically indented 2x relative to
Mark Seaborn
2013/01/16 16:03:51
You should write
if (!NaClBrokerService::GetInsta
| |
| 577 LOG(ERROR) << "NaCl process launch failed: broker service did not launch " | |
| 578 "process."; | |
| 579 return false; | |
| 580 } | |
| 571 } else { | 581 } else { |
| 572 process_->Launch(FilePath(), cmd_line.release()); | 582 process_->Launch(FilePath(), cmd_line.release()); |
| 573 } | 583 } |
| 574 #elif defined(OS_POSIX) | 584 #elif defined(OS_POSIX) |
| 575 process_->Launch(nacl_loader_prefix.empty(), // use_zygote | 585 process_->Launch(nacl_loader_prefix.empty(), // use_zygote |
| 576 base::EnvironmentVector(), | 586 base::EnvironmentVector(), |
| 577 cmd_line.release()); | 587 cmd_line.release()); |
| 578 #endif | 588 #endif |
| 579 | 589 |
| 580 return true; | 590 return true; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 599 } | 609 } |
| 600 | 610 |
| 601 void NaClProcessHost::OnProcessLaunched() { | 611 void NaClProcessHost::OnProcessLaunched() { |
| 602 if (!StartWithLaunchedProcess()) | 612 if (!StartWithLaunchedProcess()) |
| 603 delete this; | 613 delete this; |
| 604 } | 614 } |
| 605 | 615 |
| 606 // Called when the NaClBrowser singleton has been fully initialized. | 616 // Called when the NaClBrowser singleton has been fully initialized. |
| 607 void NaClProcessHost::OnResourcesReady() { | 617 void NaClProcessHost::OnResourcesReady() { |
| 608 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 618 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 609 if (!nacl_browser->IsReady() || !SendStart()) { | 619 if (!nacl_browser->IsReady()) { |
| 610 DLOG(ERROR) << "Cannot launch NaCl process"; | 620 LOG(ERROR) << "NaCl process launch failed: could not aquire shared " |
|
Mark Seaborn
2013/01/16 00:27:54
"acquire"
Nick Bray (chromium)
2013/01/16 05:54:52
Done.
| |
| 621 "resources needed by NaCl."; | |
| 622 delete this; | |
| 623 } else if (!SendStart()) { | |
| 611 delete this; | 624 delete this; |
| 612 } | 625 } |
| 613 } | 626 } |
| 614 | 627 |
| 615 bool NaClProcessHost::ReplyToRenderer( | 628 bool NaClProcessHost::ReplyToRenderer( |
| 616 const IPC::ChannelHandle& channel_handle) { | 629 const IPC::ChannelHandle& channel_handle) { |
| 617 nacl::FileDescriptor handle_for_renderer; | 630 nacl::FileDescriptor handle_for_renderer; |
| 618 #if defined(OS_WIN) | 631 #if defined(OS_WIN) |
| 619 // Copy the handle into the renderer process. | 632 // Copy the handle into the renderer process. |
| 620 HANDLE handle_in_renderer; | 633 HANDLE handle_in_renderer; |
| 621 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 634 if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
| 622 reinterpret_cast<HANDLE>( | 635 reinterpret_cast<HANDLE>( |
| 623 internal_->socket_for_renderer), | 636 internal_->socket_for_renderer), |
| 624 chrome_render_message_filter_->peer_handle(), | 637 chrome_render_message_filter_->peer_handle(), |
| 625 &handle_in_renderer, | 638 &handle_in_renderer, |
| 626 0, // Unused given DUPLICATE_SAME_ACCESS. | 639 0, // Unused given DUPLICATE_SAME_ACCESS. |
| 627 FALSE, | 640 FALSE, |
| 628 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | 641 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
| 629 DLOG(ERROR) << "DuplicateHandle() failed"; | 642 LOG(ERROR) << "DuplicateHandle() failed"; |
| 630 return false; | 643 return false; |
| 631 } | 644 } |
| 632 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>( | 645 handle_for_renderer = reinterpret_cast<nacl::FileDescriptor>( |
| 633 handle_in_renderer); | 646 handle_in_renderer); |
| 634 #else | 647 #else |
| 635 // No need to dup the imc_handle - we don't pass it anywhere else so | 648 // No need to dup the imc_handle - we don't pass it anywhere else so |
| 636 // it cannot be closed. | 649 // it cannot be closed. |
| 637 nacl::FileDescriptor imc_handle; | 650 nacl::FileDescriptor imc_handle; |
| 638 imc_handle.fd = internal_->socket_for_renderer; | 651 imc_handle.fd = internal_->socket_for_renderer; |
| 639 imc_handle.auto_close = true; | 652 imc_handle.auto_close = true; |
| 640 handle_for_renderer = imc_handle; | 653 handle_for_renderer = imc_handle; |
| 641 #endif | 654 #endif |
| 642 | 655 |
| 643 #if defined(OS_WIN) | 656 #if defined(OS_WIN) |
| 644 // If we are on 64-bit Windows, the NaCl process's sandbox is | 657 // If we are on 64-bit Windows, the NaCl process's sandbox is |
| 645 // managed by a different process from the renderer's sandbox. We | 658 // managed by a different process from the renderer's sandbox. We |
| 646 // need to inform the renderer's sandbox about the NaCl process so | 659 // need to inform the renderer's sandbox about the NaCl process so |
| 647 // that the renderer can send handles to the NaCl process using | 660 // that the renderer can send handles to the NaCl process using |
| 648 // BrokerDuplicateHandle(). | 661 // BrokerDuplicateHandle(). |
| 649 if (RunningOnWOW64()) { | 662 if (RunningOnWOW64()) { |
| 650 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { | 663 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { |
| 651 DLOG(ERROR) << "Failed to add NaCl process PID"; | 664 LOG(ERROR) << "Failed to add NaCl process PID"; |
| 652 return false; | 665 return false; |
| 653 } | 666 } |
| 654 } | 667 } |
| 655 #endif | 668 #endif |
| 656 | 669 |
| 657 const ChildProcessData& data = process_->GetData(); | 670 const ChildProcessData& data = process_->GetData(); |
| 658 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( | 671 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( |
| 659 reply_msg_, handle_for_renderer, | 672 reply_msg_, handle_for_renderer, |
| 660 channel_handle, base::GetProcId(data.handle), data.id); | 673 channel_handle, base::GetProcId(data.handle), data.id); |
| 661 chrome_render_message_filter_->Send(reply_msg_); | 674 chrome_render_message_filter_->Send(reply_msg_); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 858 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 846 | 859 |
| 847 if (nacl_browser->IsReady()) { | 860 if (nacl_browser->IsReady()) { |
| 848 return SendStart(); | 861 return SendStart(); |
| 849 } else if (nacl_browser->IsOk()) { | 862 } else if (nacl_browser->IsOk()) { |
| 850 nacl_browser->WaitForResources( | 863 nacl_browser->WaitForResources( |
| 851 base::Bind(&NaClProcessHost::OnResourcesReady, | 864 base::Bind(&NaClProcessHost::OnResourcesReady, |
| 852 weak_factory_.GetWeakPtr())); | 865 weak_factory_.GetWeakPtr())); |
| 853 return true; | 866 return true; |
| 854 } else { | 867 } else { |
| 868 LOG(ERROR) << "NaCl process failed to launch: previously failed to aquire " | |
|
Mark Seaborn
2013/01/16 00:27:54
"acquire"
Nick Bray (chromium)
2013/01/16 05:54:52
Done.
| |
| 869 "shared resources."; | |
| 855 return false; | 870 return false; |
| 856 } | 871 } |
| 857 } | 872 } |
| 858 | 873 |
| 859 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, | 874 void NaClProcessHost::OnQueryKnownToValidate(const std::string& signature, |
| 860 bool* result) { | 875 bool* result) { |
| 861 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 876 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 862 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); | 877 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); |
| 863 } | 878 } |
| 864 | 879 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 927 } else { | 942 } else { |
| 928 NaClStartDebugExceptionHandlerThread( | 943 NaClStartDebugExceptionHandlerThread( |
| 929 process_handle.Take(), info, | 944 process_handle.Take(), info, |
| 930 base::MessageLoopProxy::current(), | 945 base::MessageLoopProxy::current(), |
| 931 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 946 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 932 weak_factory_.GetWeakPtr())); | 947 weak_factory_.GetWeakPtr())); |
| 933 return true; | 948 return true; |
| 934 } | 949 } |
| 935 } | 950 } |
| 936 #endif | 951 #endif |
| OLD | NEW |