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 { // First try to open the target process in case we're not in a sandbox. |
454 if (!g_target_services) { | 466 base::win::ScopedHandle target_process; |
455 base::win::ScopedHandle target_process(::OpenProcess(PROCESS_DUP_HANDLE, | 467 target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, |
456 FALSE, | 468 target_process_id)); |
457 target_process_id)); | 469 if (target_process.IsValid()) { |
458 if (!target_process.IsValid()) | 470 return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, |
459 return false; | 471 target_process, target_handle, desired_access, |
460 | 472 FALSE, options); |
461 if (!::DuplicateHandle(::GetCurrentProcess(), source_handle, | |
462 target_process, target_handle, | |
463 desired_access, FALSE, | |
464 options)) { | |
465 return false; | |
466 } | 473 } |
467 | |
468 return true; | |
469 } | 474 } |
470 | 475 |
471 ResultCode result = g_target_services->DuplicateHandle(source_handle, | 476 // Don't broker if we're not in the sandbox or didn't get denied access. |
472 target_process_id, | 477 if (!g_target_services || ::GetLastError() != ERROR_ACCESS_DENIED) |
473 target_handle, | 478 return false; |
474 desired_access, | 479 |
475 options); | 480 return SBOX_ALL_OK == g_target_services->DuplicateHandle(source_handle, |
476 return SBOX_ALL_OK == result; | 481 target_process_id, |
| 482 target_handle, |
| 483 desired_access, |
| 484 options); |
477 } | 485 } |
478 | 486 |
479 | 487 |
480 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, | 488 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, |
481 const FilePath& exposed_dir) { | 489 const FilePath& exposed_dir) { |
482 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 490 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
483 content::ProcessType type; | 491 content::ProcessType type; |
484 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); | 492 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); |
485 if (type_str == switches::kRendererProcess) { | 493 if (type_str == switches::kRendererProcess) { |
486 type = content::PROCESS_TYPE_RENDERER; | 494 type = content::PROCESS_TYPE_RENDERER; |
(...skipping 20 matching lines...) Expand all Loading... |
507 | 515 |
508 TRACE_EVENT_BEGIN_ETW("StartProcessWithAccess", 0, type_str); | 516 TRACE_EVENT_BEGIN_ETW("StartProcessWithAccess", 0, type_str); |
509 | 517 |
510 // To decide if the process is going to be sandboxed we have two cases. | 518 // To decide if the process is going to be sandboxed we have two cases. |
511 // First case: all process types except the nacl broker, and the plugin | 519 // First case: all process types except the nacl broker, and the plugin |
512 // process are sandboxed by default. | 520 // process are sandboxed by default. |
513 bool in_sandbox = | 521 bool in_sandbox = |
514 (type != content::PROCESS_TYPE_NACL_BROKER) && | 522 (type != content::PROCESS_TYPE_NACL_BROKER) && |
515 (type != content::PROCESS_TYPE_PLUGIN) && | 523 (type != content::PROCESS_TYPE_PLUGIN) && |
516 (type != content::PROCESS_TYPE_PPAPI_BROKER); | 524 (type != content::PROCESS_TYPE_PPAPI_BROKER); |
| 525 // The handle duplication policies need the broker to track both the |
| 526 // source and target process. So, we still launch unsandboxed plugins |
| 527 // via the broker to make that work. |
| 528 bool use_broker = false; |
517 | 529 |
518 // If it is the GPU process then it can be disabled by a command line flag. | 530 // If it is the GPU process then it can be disabled by a command line flag. |
519 if ((type == content::PROCESS_TYPE_GPU) && | 531 if ((type == content::PROCESS_TYPE_GPU) && |
520 (cmd_line->HasSwitch(switches::kDisableGpuSandbox))) { | 532 (cmd_line->HasSwitch(switches::kDisableGpuSandbox))) { |
521 in_sandbox = false; | 533 in_sandbox = false; |
522 DVLOG(1) << "GPU sandbox is disabled"; | 534 DVLOG(1) << "GPU sandbox is disabled"; |
523 } | 535 } |
524 | 536 |
525 if (browser_command_line.HasSwitch(switches::kNoSandbox) || | 537 if (browser_command_line.HasSwitch(switches::kNoSandbox) || |
526 cmd_line->HasSwitch(switches::kNoSandbox)) { | 538 cmd_line->HasSwitch(switches::kNoSandbox)) { |
(...skipping 28 matching lines...) Expand all Loading... |
555 // Using a different prefetch profile per process type will allow Windows | 567 // Using a different prefetch profile per process type will allow Windows |
556 // to create separate pretetch settings for browser, renderer etc. | 568 // to create separate pretetch settings for browser, renderer etc. |
557 cmd_line->AppendArg(base::StringPrintf("/prefetch:%d", type)); | 569 cmd_line->AppendArg(base::StringPrintf("/prefetch:%d", type)); |
558 | 570 |
559 sandbox::ResultCode result; | 571 sandbox::ResultCode result; |
560 base::win::ScopedProcessInformation target; | 572 base::win::ScopedProcessInformation target; |
561 sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy(); | 573 sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy(); |
562 | 574 |
563 #if !defined(NACL_WIN64) // We don't need this code on win nacl64. | 575 #if !defined(NACL_WIN64) // We don't need this code on win nacl64. |
564 if (type == content::PROCESS_TYPE_PLUGIN && | 576 if (type == content::PROCESS_TYPE_PLUGIN && |
565 !browser_command_line.HasSwitch(switches::kNoSandbox) && | 577 !browser_command_line.HasSwitch(switches::kNoSandbox)) { |
566 content::GetContentClient()->SandboxPlugin(cmd_line, policy)) { | 578 in_sandbox = content::GetContentClient()->SandboxPlugin(cmd_line, policy); |
567 in_sandbox = true; | 579 use_broker = true; |
568 } | 580 } |
569 #endif | 581 #endif |
570 | 582 |
571 if (!in_sandbox) { | 583 if (!in_sandbox) { |
572 policy->Release(); | 584 if (!use_broker) { |
573 base::ProcessHandle process = 0; | 585 policy->Release(); |
574 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); | 586 base::ProcessHandle process = 0; |
575 return process; | 587 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); |
576 } | 588 return process; |
577 | 589 } else { |
578 if (type == content::PROCESS_TYPE_PLUGIN) { | 590 policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0); |
| 591 policy->SetTokenLevel(sandbox::USER_UNPROTECTED, |
| 592 sandbox::USER_UNPROTECTED); |
| 593 } |
| 594 } else 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 { |
585 if (!AddPolicyForRenderer(policy)) | 601 if (!AddPolicyForRenderer(policy)) |
586 return 0; | 602 return 0; |
587 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. | 603 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. |
588 // Just have to figure out what needs to be warmed up first. | 604 // Just have to figure out what needs to be warmed up first. |
(...skipping 75 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 |