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 "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_handle.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; |
| 28 static sandbox::TargetServices* g_target_services = NULL; | |
| 27 | 29 |
| 28 namespace { | 30 namespace { |
| 29 | 31 |
| 30 // The DLLs listed here are known (or under strong suspicion) of causing crashes | 32 // The DLLs listed here are known (or under strong suspicion) of causing crashes |
| 31 // when they are loaded in the renderer. Note: at runtime we generate short | 33 // when they are loaded in the renderer. Note: at runtime we generate short |
| 32 // versions of the dll name only if the dll has an extension. | 34 // versions of the dll name only if the dll has an extension. |
| 33 const wchar_t* const kTroublesomeDlls[] = { | 35 const wchar_t* const kTroublesomeDlls[] = { |
| 34 L"adialhk.dll", // Kaspersky Internet Security. | 36 L"adialhk.dll", // Kaspersky Internet Security. |
| 35 L"acpiz.dll", // Unknown. | 37 L"acpiz.dll", // Unknown. |
| 36 L"avgrsstx.dll", // AVG 8. | 38 L"avgrsstx.dll", // AVG 8. |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, | 360 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, |
| 359 L"\\\\.\\pipe\\chrome.gpu.*"); | 361 L"\\\\.\\pipe\\chrome.gpu.*"); |
| 360 if (result != sandbox::SBOX_ALL_OK) | 362 if (result != sandbox::SBOX_ALL_OK) |
| 361 return false; | 363 return false; |
| 362 | 364 |
| 363 AddGenericDllEvictionPolicy(policy); | 365 AddGenericDllEvictionPolicy(policy); |
| 364 #endif | 366 #endif |
| 365 return true; | 367 return true; |
| 366 } | 368 } |
| 367 | 369 |
| 368 void AddPolicyForRenderer(sandbox::TargetPolicy* policy) { | 370 bool AddPolicyForRenderer(sandbox::TargetPolicy* policy) { |
| 371 // Renderers need to copy sections for plugin DIBs. | |
| 372 sandbox::ResultCode result; | |
| 373 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, | |
| 374 sandbox::TargetPolicy::HANDLES_DUP_ANY, | |
| 375 L"Section"); | |
| 376 if (result != sandbox::SBOX_ALL_OK) { | |
| 377 NOTREACHED(); | |
| 378 return false; | |
| 379 } | |
| 380 | |
| 369 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); | 381 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); |
| 370 | 382 |
| 371 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; | 383 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; |
| 372 if (base::win::GetVersion() > base::win::VERSION_XP) { | 384 if (base::win::GetVersion() > base::win::VERSION_XP) { |
| 373 // On 2003/Vista the initial token has to be restricted if the main | 385 // On 2003/Vista the initial token has to be restricted if the main |
| 374 // token is restricted. | 386 // token is restricted. |
| 375 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; | 387 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; |
| 376 } | 388 } |
| 377 | 389 |
| 378 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); | 390 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); |
| 379 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | 391 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); |
| 380 | 392 |
| 381 bool use_winsta = !CommandLine::ForCurrentProcess()->HasSwitch( | 393 bool use_winsta = !CommandLine::ForCurrentProcess()->HasSwitch( |
| 382 switches::kDisableAltWinstation); | 394 switches::kDisableAltWinstation); |
| 383 | 395 |
| 384 if (sandbox::SBOX_ALL_OK != policy->SetAlternateDesktop(use_winsta)) { | 396 if (sandbox::SBOX_ALL_OK != policy->SetAlternateDesktop(use_winsta)) { |
| 385 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; | 397 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; |
| 386 } | 398 } |
| 387 | 399 |
| 388 AddGenericDllEvictionPolicy(policy); | 400 AddGenericDllEvictionPolicy(policy); |
| 401 | |
| 402 return true; | |
| 389 } | 403 } |
| 390 | 404 |
| 391 // The Pepper process as locked-down as a renderer execpt that it can | 405 // The Pepper process as locked-down as a renderer execpt that it can |
| 392 // create the server side of chrome pipes. | 406 // create the server side of chrome pipes. |
| 393 bool AddPolicyForPepperPlugin(sandbox::TargetPolicy* policy) { | 407 bool AddPolicyForPepperPlugin(sandbox::TargetPolicy* policy) { |
| 394 sandbox::ResultCode result; | 408 sandbox::ResultCode result; |
| 395 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, | 409 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, |
| 396 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, | 410 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, |
| 397 L"\\\\.\\pipe\\chrome.*"); | 411 L"\\\\.\\pipe\\chrome.*"); |
| 398 if (result != sandbox::SBOX_ALL_OK) { | 412 if (result != sandbox::SBOX_ALL_OK) { |
| 399 NOTREACHED(); | 413 NOTREACHED(); |
| 400 return false; | 414 return false; |
| 401 } | 415 } |
| 402 AddPolicyForRenderer(policy); | 416 return AddPolicyForRenderer(policy); |
| 403 return true; | |
| 404 } | 417 } |
| 405 | 418 |
| 406 } // namespace | 419 } // namespace |
| 407 | 420 |
| 408 namespace sandbox { | 421 namespace sandbox { |
| 409 | 422 |
| 410 void InitBrokerServices(sandbox::BrokerServices* broker_services) { | 423 bool InitBrokerServices(sandbox::BrokerServices* broker_services) { |
| 411 // TODO(abarth): DCHECK(CalledOnValidThread()); | 424 // TODO(abarth): DCHECK(CalledOnValidThread()); |
| 412 // See <http://b/1287166>. | 425 // See <http://b/1287166>. |
| 413 DCHECK(broker_services); | 426 DCHECK(broker_services); |
| 414 DCHECK(!g_broker_services); | 427 DCHECK(!g_broker_services); |
| 415 broker_services->Init(); | 428 sandbox::ResultCode result = broker_services->Init(); |
| 416 g_broker_services = broker_services; | 429 g_broker_services = broker_services; |
| 430 return SBOX_ALL_OK == result; | |
| 417 } | 431 } |
| 418 | 432 |
| 433 bool InitTargetServices(sandbox::TargetServices* target_services) { | |
| 434 DCHECK(target_services); | |
| 435 DCHECK(!g_target_services); | |
| 436 sandbox::ResultCode result = target_services->Init(); | |
| 437 g_target_services = target_services; | |
| 438 return SBOX_ALL_OK == result; | |
| 439 } | |
| 440 | |
| 441 bool BrokerDuplicateHandle(HANDLE source_handle, | |
| 442 DWORD target_process_id, | |
| 443 HANDLE* target_handle, | |
| 444 DWORD desired_access, | |
| 445 BOOL inherit_handle, | |
|
nsylvain
2012/03/28 13:11:46
i dont think you should be supporting inherit_hand
jschuh
2012/03/28 22:09:29
Fair point. I'll remove it entirely.
| |
| 446 DWORD options) { | |
| 447 // Just use DuplicateHandle() if we aren't in the sandbox. | |
| 448 if (!g_target_services) { | |
| 449 base::win::ScopedHandle target_process(::OpenProcess(PROCESS_DUP_HANDLE, | |
| 450 FALSE, | |
| 451 target_process_id)); | |
| 452 if (!target_process.IsValid()) | |
| 453 return false; | |
| 454 | |
| 455 if (!::DuplicateHandle(::GetCurrentProcess(), source_handle, | |
| 456 target_process, target_handle, | |
| 457 desired_access, inherit_handle, | |
| 458 options)) { | |
| 459 return false; | |
| 460 } | |
| 461 | |
| 462 return true; | |
| 463 } | |
| 464 | |
| 465 ResultCode result = g_target_services->DuplicateHandle(source_handle, | |
| 466 target_process_id, | |
| 467 target_handle, | |
| 468 desired_access, | |
| 469 inherit_handle, | |
| 470 options); | |
| 471 return SBOX_ALL_OK == result; | |
| 472 } | |
| 473 | |
| 474 | |
| 419 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, | 475 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, |
| 420 const FilePath& exposed_dir) { | 476 const FilePath& exposed_dir) { |
| 421 base::ProcessHandle process = 0; | 477 base::ProcessHandle process = 0; |
| 422 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 478 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 423 content::ProcessType type; | 479 content::ProcessType type; |
| 424 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); | 480 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 425 if (type_str == switches::kRendererProcess) { | 481 if (type_str == switches::kRendererProcess) { |
| 426 type = content::PROCESS_TYPE_RENDERER; | 482 type = content::PROCESS_TYPE_RENDERER; |
| 427 } else if (type_str == switches::kPluginProcess) { | 483 } else if (type_str == switches::kPluginProcess) { |
| 428 type = content::PROCESS_TYPE_PLUGIN; | 484 type = content::PROCESS_TYPE_PLUGIN; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 517 if (type == content::PROCESS_TYPE_PLUGIN) { | 573 if (type == content::PROCESS_TYPE_PLUGIN) { |
| 518 AddGenericDllEvictionPolicy(policy); | 574 AddGenericDllEvictionPolicy(policy); |
| 519 AddPluginDllEvictionPolicy(policy); | 575 AddPluginDllEvictionPolicy(policy); |
| 520 } else if (type == content::PROCESS_TYPE_GPU) { | 576 } else if (type == content::PROCESS_TYPE_GPU) { |
| 521 if (!AddPolicyForGPU(cmd_line, policy)) | 577 if (!AddPolicyForGPU(cmd_line, policy)) |
| 522 return 0; | 578 return 0; |
| 523 } else if (type == content::PROCESS_TYPE_PPAPI_PLUGIN) { | 579 } else if (type == content::PROCESS_TYPE_PPAPI_PLUGIN) { |
| 524 if (!AddPolicyForPepperPlugin(policy)) | 580 if (!AddPolicyForPepperPlugin(policy)) |
| 525 return 0; | 581 return 0; |
| 526 } else { | 582 } else { |
| 527 AddPolicyForRenderer(policy); | 583 if (!AddPolicyForRenderer(policy)) |
| 584 return 0; | |
| 528 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. | 585 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. |
| 529 // Just have to figure out what needs to be warmed up first. | 586 // Just have to figure out what needs to be warmed up first. |
| 530 if (type == content::PROCESS_TYPE_RENDERER || | 587 if (type == content::PROCESS_TYPE_RENDERER || |
| 531 type == content::PROCESS_TYPE_WORKER) { | 588 type == content::PROCESS_TYPE_WORKER) { |
| 532 AddBaseHandleClosePolicy(policy); | 589 AddBaseHandleClosePolicy(policy); |
| 533 } | 590 } |
| 534 | 591 |
| 535 if (type_str != switches::kRendererProcess) { | 592 if (type_str != switches::kRendererProcess) { |
| 536 // Hack for Google Desktop crash. Trick GD into not injecting its DLL into | 593 // Hack for Google Desktop crash. Trick GD into not injecting its DLL into |
| 537 // this subprocess. See | 594 // this subprocess. See |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 | 658 |
| 602 // Help the process a little. It can't start the debugger by itself if | 659 // Help the process a little. It can't start the debugger by itself if |
| 603 // the process is in a sandbox. | 660 // the process is in a sandbox. |
| 604 if (child_needs_help) | 661 if (child_needs_help) |
| 605 base::debug::SpawnDebuggerOnProcess(target.dwProcessId); | 662 base::debug::SpawnDebuggerOnProcess(target.dwProcessId); |
| 606 | 663 |
| 607 return process; | 664 return process; |
| 608 } | 665 } |
| 609 | 666 |
| 610 } // namespace sandbox | 667 } // namespace sandbox |
| OLD | NEW |