| 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" |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 | 366 |
| 367 // Allow the server side of GPU sockets, which are pipes that have | 367 // Allow the server side of GPU sockets, which are pipes that have |
| 368 // the "chrome.gpu" namespace and an arbitrary suffix. | 368 // the "chrome.gpu" namespace and an arbitrary suffix. |
| 369 sandbox::ResultCode result = policy->AddRule( | 369 sandbox::ResultCode result = policy->AddRule( |
| 370 sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, | 370 sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, |
| 371 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, | 371 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, |
| 372 L"\\\\.\\pipe\\chrome.gpu.*"); | 372 L"\\\\.\\pipe\\chrome.gpu.*"); |
| 373 if (result != sandbox::SBOX_ALL_OK) | 373 if (result != sandbox::SBOX_ALL_OK) |
| 374 return false; | 374 return false; |
| 375 | 375 |
| 376 // GPU needs to copy sections to renderers. |
| 377 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, |
| 378 sandbox::TargetPolicy::HANDLES_DUP_ANY, |
| 379 L"Section"); |
| 380 if (result != sandbox::SBOX_ALL_OK) |
| 381 return false; |
| 382 |
| 376 AddGenericDllEvictionPolicy(policy); | 383 AddGenericDllEvictionPolicy(policy); |
| 377 #endif | 384 #endif |
| 378 return true; | 385 return true; |
| 379 } | 386 } |
| 380 | 387 |
| 381 bool AddPolicyForRenderer(sandbox::TargetPolicy* policy) { | 388 bool AddPolicyForRenderer(sandbox::TargetPolicy* policy) { |
| 382 // Renderers need to copy sections for plugin DIBs. | 389 // Renderers need to copy sections for plugin DIBs and GPU. |
| 383 sandbox::ResultCode result; | 390 sandbox::ResultCode result; |
| 384 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, | 391 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, |
| 385 sandbox::TargetPolicy::HANDLES_DUP_ANY, | 392 sandbox::TargetPolicy::HANDLES_DUP_ANY, |
| 386 L"Section"); | 393 L"Section"); |
| 387 if (result != sandbox::SBOX_ALL_OK) { | 394 if (result != sandbox::SBOX_ALL_OK) |
| 388 NOTREACHED(); | |
| 389 return false; | 395 return false; |
| 390 } | 396 |
| 397 // Renderers need to share events with plugins. |
| 398 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, |
| 399 sandbox::TargetPolicy::HANDLES_DUP_ANY, |
| 400 L"Event"); |
| 401 if (result != sandbox::SBOX_ALL_OK) |
| 402 return false; |
| 391 | 403 |
| 392 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); | 404 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); |
| 393 | 405 |
| 394 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; | 406 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; |
| 395 if (base::win::GetVersion() > base::win::VERSION_XP) { | 407 if (base::win::GetVersion() > base::win::VERSION_XP) { |
| 396 // On 2003/Vista the initial token has to be restricted if the main | 408 // On 2003/Vista the initial token has to be restricted if the main |
| 397 // token is restricted. | 409 // token is restricted. |
| 398 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; | 410 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; |
| 399 } | 411 } |
| 400 | 412 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 sandbox::ResultCode result = target_services->Init(); | 455 sandbox::ResultCode result = target_services->Init(); |
| 444 g_target_services = target_services; | 456 g_target_services = target_services; |
| 445 return SBOX_ALL_OK == result; | 457 return SBOX_ALL_OK == result; |
| 446 } | 458 } |
| 447 | 459 |
| 448 bool BrokerDuplicateHandle(HANDLE source_handle, | 460 bool BrokerDuplicateHandle(HANDLE source_handle, |
| 449 DWORD target_process_id, | 461 DWORD target_process_id, |
| 450 HANDLE* target_handle, | 462 HANDLE* target_handle, |
| 451 DWORD desired_access, | 463 DWORD desired_access, |
| 452 DWORD options) { | 464 DWORD options) { |
| 453 // Just use DuplicateHandle() if we aren't in the sandbox. | 465 // If our process is the target just duplicate the handle. |
| 454 if (!g_target_services) { | 466 if (::GetCurrentProcessId() == target_process_id) { |
| 455 base::win::ScopedHandle target_process(::OpenProcess(PROCESS_DUP_HANDLE, | 467 return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, |
| 456 FALSE, | 468 ::GetCurrentProcess(), target_handle, |
| 457 target_process_id)); | 469 desired_access, FALSE, options); |
| 458 if (!target_process.IsValid()) | |
| 459 return false; | |
| 460 | 470 |
| 461 if (!::DuplicateHandle(::GetCurrentProcess(), source_handle, | 471 } |
| 462 target_process, target_handle, | |
| 463 desired_access, FALSE, | |
| 464 options)) { | |
| 465 return false; | |
| 466 } | |
| 467 | 472 |
| 473 // Try the broker next |
| 474 if (g_target_services && |
| 475 g_target_services->DuplicateHandle(source_handle, target_process_id, |
| 476 target_handle, desired_access, |
| 477 options) == SBOX_ALL_OK) { |
| 468 return true; | 478 return true; |
| 469 } | 479 } |
| 470 | 480 |
| 471 ResultCode result = g_target_services->DuplicateHandle(source_handle, | 481 // Finally, see if we already have access to the process. |
| 472 target_process_id, | 482 base::win::ScopedHandle target_process; |
| 473 target_handle, | 483 target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, |
| 474 desired_access, | 484 target_process_id)); |
| 475 options); | 485 if (target_process.IsValid()) { |
| 476 return SBOX_ALL_OK == result; | 486 return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, |
| 487 target_process, target_handle, |
| 488 desired_access, FALSE, options); |
| 489 } |
| 490 |
| 491 return false; |
| 477 } | 492 } |
| 478 | 493 |
| 479 | 494 |
| 480 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, | 495 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, |
| 481 const FilePath& exposed_dir) { | 496 const FilePath& exposed_dir) { |
| 482 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 497 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 483 content::ProcessType type; | 498 content::ProcessType type; |
| 484 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); | 499 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 485 if (type_str == switches::kRendererProcess) { | 500 if (type_str == switches::kRendererProcess) { |
| 486 type = content::PROCESS_TYPE_RENDERER; | 501 type = content::PROCESS_TYPE_RENDERER; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 !browser_command_line.HasSwitch(switches::kNoSandbox) && | 580 !browser_command_line.HasSwitch(switches::kNoSandbox) && |
| 566 content::GetContentClient()->SandboxPlugin(cmd_line, policy)) { | 581 content::GetContentClient()->SandboxPlugin(cmd_line, policy)) { |
| 567 in_sandbox = true; | 582 in_sandbox = true; |
| 568 } | 583 } |
| 569 #endif | 584 #endif |
| 570 | 585 |
| 571 if (!in_sandbox) { | 586 if (!in_sandbox) { |
| 572 policy->Release(); | 587 policy->Release(); |
| 573 base::ProcessHandle process = 0; | 588 base::ProcessHandle process = 0; |
| 574 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); | 589 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); |
| 590 g_broker_services->AddTargetPeer(process); |
| 575 return process; | 591 return process; |
| 576 } | 592 } |
| 577 | 593 |
| 578 if (type == content::PROCESS_TYPE_PLUGIN) { | 594 if (type == content::PROCESS_TYPE_PLUGIN) { |
| 579 AddGenericDllEvictionPolicy(policy); | 595 AddGenericDllEvictionPolicy(policy); |
| 580 AddPluginDllEvictionPolicy(policy); | 596 AddPluginDllEvictionPolicy(policy); |
| 581 } else if (type == content::PROCESS_TYPE_GPU) { | 597 } else if (type == content::PROCESS_TYPE_GPU) { |
| 582 if (!AddPolicyForGPU(cmd_line, policy)) | 598 if (!AddPolicyForGPU(cmd_line, policy)) |
| 583 return 0; | 599 return 0; |
| 584 } else { | 600 } else { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 | 680 |
| 665 // Help the process a little. It can't start the debugger by itself if | 681 // Help the process a little. It can't start the debugger by itself if |
| 666 // the process is in a sandbox. | 682 // the process is in a sandbox. |
| 667 if (child_needs_help) | 683 if (child_needs_help) |
| 668 base::debug::SpawnDebuggerOnProcess(target.process_id()); | 684 base::debug::SpawnDebuggerOnProcess(target.process_id()); |
| 669 | 685 |
| 670 return target.TakeProcessHandle(); | 686 return target.TakeProcessHandle(); |
| 671 } | 687 } |
| 672 | 688 |
| 673 } // namespace sandbox | 689 } // namespace sandbox |
| OLD | NEW |