| 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 "content/common/sandbox_policy.h" | 5 #include "content/common/sandbox_policy.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/debugger.h" | 10 #include "base/debug/debugger.h" |
| 11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 16 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/win/scoped_process_information.h" |
| 18 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
| 19 #include "content/common/debug_flags.h" | 20 #include "content/common/debug_flags.h" |
| 20 #include "content/public/common/content_client.h" | 21 #include "content/public/common/content_client.h" |
| 21 #include "content/public/common/content_switches.h" | 22 #include "content/public/common/content_switches.h" |
| 22 #include "content/public/common/process_type.h" | 23 #include "content/public/common/process_type.h" |
| 23 #include "sandbox/src/sandbox.h" | 24 #include "sandbox/src/sandbox.h" |
| 24 #include "ui/gfx/gl/gl_switches.h" | 25 #include "ui/gfx/gl/gl_switches.h" |
| 25 | 26 |
| 26 static sandbox::BrokerServices* g_broker_services = NULL; | 27 static sandbox::BrokerServices* g_broker_services = NULL; |
| 27 | 28 |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 // TODO(abarth): DCHECK(CalledOnValidThread()); | 412 // TODO(abarth): DCHECK(CalledOnValidThread()); |
| 412 // See <http://b/1287166>. | 413 // See <http://b/1287166>. |
| 413 DCHECK(broker_services); | 414 DCHECK(broker_services); |
| 414 DCHECK(!g_broker_services); | 415 DCHECK(!g_broker_services); |
| 415 broker_services->Init(); | 416 broker_services->Init(); |
| 416 g_broker_services = broker_services; | 417 g_broker_services = broker_services; |
| 417 } | 418 } |
| 418 | 419 |
| 419 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, | 420 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, |
| 420 const FilePath& exposed_dir) { | 421 const FilePath& exposed_dir) { |
| 421 base::ProcessHandle process = 0; | |
| 422 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 422 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 423 content::ProcessType type; | 423 content::ProcessType type; |
| 424 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); | 424 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 425 if (type_str == switches::kRendererProcess) { | 425 if (type_str == switches::kRendererProcess) { |
| 426 type = content::PROCESS_TYPE_RENDERER; | 426 type = content::PROCESS_TYPE_RENDERER; |
| 427 } else if (type_str == switches::kPluginProcess) { | 427 } else if (type_str == switches::kPluginProcess) { |
| 428 type = content::PROCESS_TYPE_PLUGIN; | 428 type = content::PROCESS_TYPE_PLUGIN; |
| 429 } else if (type_str == switches::kWorkerProcess) { | 429 } else if (type_str == switches::kWorkerProcess) { |
| 430 type = content::PROCESS_TYPE_WORKER; | 430 type = content::PROCESS_TYPE_WORKER; |
| 431 } else if (type_str == switches::kNaClLoaderProcess) { | 431 } else if (type_str == switches::kNaClLoaderProcess) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 | 490 |
| 491 bool child_needs_help = | 491 bool child_needs_help = |
| 492 DebugFlags::ProcessDebugFlags(cmd_line, type, in_sandbox); | 492 DebugFlags::ProcessDebugFlags(cmd_line, type, in_sandbox); |
| 493 | 493 |
| 494 // Prefetch hints on windows: | 494 // Prefetch hints on windows: |
| 495 // Using a different prefetch profile per process type will allow Windows | 495 // Using a different prefetch profile per process type will allow Windows |
| 496 // to create separate pretetch settings for browser, renderer etc. | 496 // to create separate pretetch settings for browser, renderer etc. |
| 497 cmd_line->AppendArg(base::StringPrintf("/prefetch:%d", type)); | 497 cmd_line->AppendArg(base::StringPrintf("/prefetch:%d", type)); |
| 498 | 498 |
| 499 sandbox::ResultCode result; | 499 sandbox::ResultCode result; |
| 500 PROCESS_INFORMATION target = {0}; | 500 base::win::ScopedProcessInformation target; |
| 501 sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy(); | 501 sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy(); |
| 502 | 502 |
| 503 #if !defined(NACL_WIN64) // We don't need this code on win nacl64. | 503 #if !defined(NACL_WIN64) // We don't need this code on win nacl64. |
| 504 if (type == content::PROCESS_TYPE_PLUGIN && | 504 if (type == content::PROCESS_TYPE_PLUGIN && |
| 505 !browser_command_line.HasSwitch(switches::kNoSandbox) && | 505 !browser_command_line.HasSwitch(switches::kNoSandbox) && |
| 506 content::GetContentClient()->SandboxPlugin(cmd_line, policy)) { | 506 content::GetContentClient()->SandboxPlugin(cmd_line, policy)) { |
| 507 in_sandbox = true; | 507 in_sandbox = true; |
| 508 } | 508 } |
| 509 #endif | 509 #endif |
| 510 | 510 |
| 511 if (!in_sandbox) { | 511 if (!in_sandbox) { |
| 512 policy->Release(); | 512 policy->Release(); |
| 513 base::ProcessHandle process = 0; |
| 513 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); | 514 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); |
| 514 return process; | 515 return process; |
| 515 } | 516 } |
| 516 | 517 |
| 517 if (type == content::PROCESS_TYPE_PLUGIN) { | 518 if (type == content::PROCESS_TYPE_PLUGIN) { |
| 518 AddGenericDllEvictionPolicy(policy); | 519 AddGenericDllEvictionPolicy(policy); |
| 519 AddPluginDllEvictionPolicy(policy); | 520 AddPluginDllEvictionPolicy(policy); |
| 520 } else if (type == content::PROCESS_TYPE_GPU) { | 521 } else if (type == content::PROCESS_TYPE_GPU) { |
| 521 if (!AddPolicyForGPU(cmd_line, policy)) | 522 if (!AddPolicyForGPU(cmd_line, policy)) |
| 522 return 0; | 523 return 0; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 if (!AddGenericPolicy(policy)) { | 559 if (!AddGenericPolicy(policy)) { |
| 559 NOTREACHED(); | 560 NOTREACHED(); |
| 560 return 0; | 561 return 0; |
| 561 } | 562 } |
| 562 | 563 |
| 563 TRACE_EVENT_BEGIN_ETW("StartProcessWithAccess::LAUNCHPROCESS", 0, 0); | 564 TRACE_EVENT_BEGIN_ETW("StartProcessWithAccess::LAUNCHPROCESS", 0, 0); |
| 564 | 565 |
| 565 result = g_broker_services->SpawnTarget( | 566 result = g_broker_services->SpawnTarget( |
| 566 cmd_line->GetProgram().value().c_str(), | 567 cmd_line->GetProgram().value().c_str(), |
| 567 cmd_line->GetCommandLineString().c_str(), | 568 cmd_line->GetCommandLineString().c_str(), |
| 568 policy, &target); | 569 policy, target.Receive()); |
| 569 policy->Release(); | 570 policy->Release(); |
| 570 | 571 |
| 571 TRACE_EVENT_END_ETW("StartProcessWithAccess::LAUNCHPROCESS", 0, 0); | 572 TRACE_EVENT_END_ETW("StartProcessWithAccess::LAUNCHPROCESS", 0, 0); |
| 572 | 573 |
| 573 if (sandbox::SBOX_ALL_OK != result) { | 574 if (sandbox::SBOX_ALL_OK != result) { |
| 574 DLOG(ERROR) << "Failed to launch process. Error: " << result; | 575 DLOG(ERROR) << "Failed to launch process. Error: " << result; |
| 575 return 0; | 576 return 0; |
| 576 } | 577 } |
| 577 | 578 |
| 578 // For Native Client sel_ldr processes on 32-bit Windows, reserve 1 GB of | 579 // For Native Client sel_ldr processes on 32-bit Windows, reserve 1 GB of |
| 579 // address space to prevent later failure due to address space fragmentation | 580 // address space to prevent later failure due to address space fragmentation |
| 580 // from .dll loading. The NaCl process will attempt to locate this space by | 581 // from .dll loading. The NaCl process will attempt to locate this space by |
| 581 // scanning the address space using VirtualQuery. | 582 // scanning the address space using VirtualQuery. |
| 582 // TODO(bbudge) Handle the --no-sandbox case. | 583 // TODO(bbudge) Handle the --no-sandbox case. |
| 583 // http://code.google.com/p/nativeclient/issues/detail?id=2131 | 584 // http://code.google.com/p/nativeclient/issues/detail?id=2131 |
| 584 if (type == content::PROCESS_TYPE_NACL_LOADER && | 585 if (type == content::PROCESS_TYPE_NACL_LOADER && |
| 585 (base::win::OSInfo::GetInstance()->wow64_status() == | 586 (base::win::OSInfo::GetInstance()->wow64_status() == |
| 586 base::win::OSInfo::WOW64_DISABLED)) { | 587 base::win::OSInfo::WOW64_DISABLED)) { |
| 587 const SIZE_T kOneGigabyte = 1 << 30; | 588 const SIZE_T kOneGigabyte = 1 << 30; |
| 588 void* nacl_mem = VirtualAllocEx(target.hProcess, | 589 void* nacl_mem = VirtualAllocEx(target.process_handle(), |
| 589 NULL, | 590 NULL, |
| 590 kOneGigabyte, | 591 kOneGigabyte, |
| 591 MEM_RESERVE, | 592 MEM_RESERVE, |
| 592 PAGE_NOACCESS); | 593 PAGE_NOACCESS); |
| 593 if (!nacl_mem) { | 594 if (!nacl_mem) { |
| 594 DLOG(WARNING) << "Failed to reserve address space for Native Client"; | 595 DLOG(WARNING) << "Failed to reserve address space for Native Client"; |
| 595 } | 596 } |
| 596 } | 597 } |
| 597 | 598 |
| 598 ResumeThread(target.hThread); | 599 ResumeThread(target.thread_handle()); |
| 599 CloseHandle(target.hThread); | |
| 600 process = target.hProcess; | |
| 601 | 600 |
| 602 // Help the process a little. It can't start the debugger by itself if | 601 // Help the process a little. It can't start the debugger by itself if |
| 603 // the process is in a sandbox. | 602 // the process is in a sandbox. |
| 604 if (child_needs_help) | 603 if (child_needs_help) |
| 605 base::debug::SpawnDebuggerOnProcess(target.dwProcessId); | 604 base::debug::SpawnDebuggerOnProcess(target.process_id()); |
| 606 | 605 |
| 607 return process; | 606 return target.TakeProcessHandle(); |
| 608 } | 607 } |
| 609 | 608 |
| 610 } // namespace sandbox | 609 } // namespace sandbox |
| OLD | NEW |