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 |