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