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