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 13 matching lines...) Expand all Loading... | |
24 #include "content/public/common/content_client.h" | 24 #include "content/public/common/content_client.h" |
25 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
26 #include "content/public/common/process_type.h" | 26 #include "content/public/common/process_type.h" |
27 #include "content/public/common/sandbox_init.h" | 27 #include "content/public/common/sandbox_init.h" |
28 #include "sandbox/win/src/process_mitigations.h" | 28 #include "sandbox/win/src/process_mitigations.h" |
29 #include "sandbox/win/src/sandbox.h" | 29 #include "sandbox/win/src/sandbox.h" |
30 #include "sandbox/win/src/sandbox_nt_util.h" | 30 #include "sandbox/win/src/sandbox_nt_util.h" |
31 #include "sandbox/win/src/win_utils.h" | 31 #include "sandbox/win/src/win_utils.h" |
32 #include "ui/gl/gl_switches.h" | 32 #include "ui/gl/gl_switches.h" |
33 | 33 |
34 static sandbox::BrokerServices* g_broker_services = NULL; | 34 namespace content { |
35 static sandbox::TargetServices* g_target_services = NULL; | |
36 | |
37 namespace { | 35 namespace { |
36 sandbox::BrokerServices* g_broker_services = NULL; | |
37 sandbox::TargetServices* g_target_services = NULL; | |
38 base::LazyInstance<SandboxedProcessStartingCallback> | |
39 g_sandboxed_process_starting_callback = LAZY_INSTANCE_INITIALIZER; | |
38 | 40 |
39 // The DLLs listed here are known (or under strong suspicion) of causing crashes | 41 // The DLLs listed here are known (or under strong suspicion) of causing crashes |
40 // when they are loaded in the renderer. Note: at runtime we generate short | 42 // when they are loaded in the renderer. Note: at runtime we generate short |
41 // versions of the dll name only if the dll has an extension. | 43 // versions of the dll name only if the dll has an extension. |
42 const wchar_t* const kTroublesomeDlls[] = { | 44 const wchar_t* const kTroublesomeDlls[] = { |
43 L"adialhk.dll", // Kaspersky Internet Security. | 45 L"adialhk.dll", // Kaspersky Internet Security. |
44 L"acpiz.dll", // Unknown. | 46 L"acpiz.dll", // Unknown. |
45 L"avgrsstx.dll", // AVG 8. | 47 L"avgrsstx.dll", // AVG 8. |
46 L"babylonchromepi.dll", // Babylon translator. | 48 L"babylonchromepi.dll", // Babylon translator. |
47 L"btkeyind.dll", // Widcomm Bluetooth. | 49 L"btkeyind.dll", // Widcomm Bluetooth. |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 sandbox::ResultCode result; | 318 sandbox::ResultCode result; |
317 | 319 |
318 // Add the policy for the client side of a pipe. It is just a file | 320 // Add the policy for the client side of a pipe. It is just a file |
319 // in the \pipe\ namespace. We restrict it to pipes that start with | 321 // in the \pipe\ namespace. We restrict it to pipes that start with |
320 // "chrome." so the sandboxed process cannot connect to system services. | 322 // "chrome." so the sandboxed process cannot connect to system services. |
321 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, | 323 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, |
322 sandbox::TargetPolicy::FILES_ALLOW_ANY, | 324 sandbox::TargetPolicy::FILES_ALLOW_ANY, |
323 L"\\??\\pipe\\chrome.*"); | 325 L"\\??\\pipe\\chrome.*"); |
324 if (result != sandbox::SBOX_ALL_OK) | 326 if (result != sandbox::SBOX_ALL_OK) |
325 return false; | 327 return false; |
326 // Allow the server side of a pipe restricted to the "chrome.nacl." | 328 |
327 // namespace so that it cannot impersonate other system or other chrome | |
328 // service pipes. | |
329 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, | |
330 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, | |
331 L"\\\\.\\pipe\\chrome.nacl.*"); | |
332 if (result != sandbox::SBOX_ALL_OK) | |
333 return false; | |
334 // Allow the server side of sync sockets, which are pipes that have | 329 // Allow the server side of sync sockets, which are pipes that have |
335 // the "chrome.sync" namespace and a randomly generated suffix. | 330 // the "chrome.sync" namespace and a randomly generated suffix. |
336 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, | 331 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, |
337 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, | 332 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, |
338 L"\\\\.\\pipe\\chrome.sync.*"); | 333 L"\\\\.\\pipe\\chrome.sync.*"); |
339 if (result != sandbox::SBOX_ALL_OK) | 334 if (result != sandbox::SBOX_ALL_OK) |
340 return false; | 335 return false; |
341 | 336 |
342 // Add the policy for debug message only in debug | 337 // Add the policy for debug message only in debug |
343 #ifndef NDEBUG | 338 #ifndef NDEBUG |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 if (result != sandbox::SBOX_ALL_OK) | 465 if (result != sandbox::SBOX_ALL_OK) |
471 return false; | 466 return false; |
472 | 467 |
473 // Renderers need to share events with plugins. | 468 // Renderers need to share events with plugins. |
474 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, | 469 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, |
475 sandbox::TargetPolicy::HANDLES_DUP_ANY, | 470 sandbox::TargetPolicy::HANDLES_DUP_ANY, |
476 L"Event"); | 471 L"Event"); |
477 if (result != sandbox::SBOX_ALL_OK) | 472 if (result != sandbox::SBOX_ALL_OK) |
478 return false; | 473 return false; |
479 | 474 |
480 // Renderers need to send named pipe handles and shared memory | |
481 // segment handles to NaCl loader processes. | |
482 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, | |
483 sandbox::TargetPolicy::HANDLES_DUP_ANY, | |
484 L"File"); | |
485 if (result != sandbox::SBOX_ALL_OK) | |
486 return false; | |
487 | |
488 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; | 475 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; |
489 if (base::win::GetVersion() > base::win::VERSION_XP) { | 476 if (base::win::GetVersion() > base::win::VERSION_XP) { |
490 // On 2003/Vista the initial token has to be restricted if the main | 477 // On 2003/Vista the initial token has to be restricted if the main |
491 // token is restricted. | 478 // token is restricted. |
492 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; | 479 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; |
493 } | 480 } |
494 | 481 |
495 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); | 482 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); |
496 // Prevents the renderers from manipulating low-integrity processes. | 483 // Prevents the renderers from manipulating low-integrity processes. |
497 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED); | 484 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
611 // Callers use CHECK macro to make sure we get the right stack. | 598 // Callers use CHECK macro to make sure we get the right stack. |
612 CheckDuplicateHandle(handle); | 599 CheckDuplicateHandle(handle); |
613 } | 600 } |
614 | 601 |
615 return TRUE; | 602 return TRUE; |
616 } | 603 } |
617 #endif | 604 #endif |
618 | 605 |
619 } // namespace | 606 } // namespace |
620 | 607 |
621 namespace content { | |
622 | |
623 bool InitBrokerServices(sandbox::BrokerServices* broker_services) { | 608 bool InitBrokerServices(sandbox::BrokerServices* broker_services) { |
624 // TODO(abarth): DCHECK(CalledOnValidThread()); | 609 // TODO(abarth): DCHECK(CalledOnValidThread()); |
625 // See <http://b/1287166>. | 610 // See <http://b/1287166>. |
626 DCHECK(broker_services); | 611 DCHECK(broker_services); |
627 DCHECK(!g_broker_services); | 612 DCHECK(!g_broker_services); |
628 sandbox::ResultCode result = broker_services->Init(); | 613 sandbox::ResultCode result = broker_services->Init(); |
629 g_broker_services = broker_services; | 614 g_broker_services = broker_services; |
630 | 615 |
631 // In non-official builds warn about dangerous uses of DuplicateHandle. | 616 // In non-official builds warn about dangerous uses of DuplicateHandle. |
632 BOOL is_in_job = FALSE; | 617 BOOL is_in_job = FALSE; |
633 #ifdef NACL_WIN64 | 618 #ifdef NACL_WIN64 |
634 CHECK(::IsProcessInJob(::GetCurrentProcess(), NULL, &is_in_job)); | 619 CHECK(::IsProcessInJob(::GetCurrentProcess(), NULL, &is_in_job)); |
635 #endif | 620 #endif |
636 #ifndef OFFICIAL_BUILD | 621 #ifndef OFFICIAL_BUILD |
637 if (!is_in_job && !g_iat_patch_duplicate_handle.is_patched()) { | 622 if (!is_in_job && !g_iat_patch_duplicate_handle.is_patched()) { |
638 HMODULE module = NULL; | 623 HMODULE module = NULL; |
639 wchar_t module_name[MAX_PATH]; | 624 wchar_t module_name[MAX_PATH]; |
640 CHECK(::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, | 625 CHECK(::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, |
641 reinterpret_cast<LPCWSTR>(InitBrokerServices), | 626 reinterpret_cast<LPCWSTR>(InitBrokerServices), |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
813 exposed_files.value().c_str()); | 798 exposed_files.value().c_str()); |
814 if (result != sandbox::SBOX_ALL_OK) | 799 if (result != sandbox::SBOX_ALL_OK) |
815 return 0; | 800 return 0; |
816 } | 801 } |
817 | 802 |
818 if (!AddGenericPolicy(policy)) { | 803 if (!AddGenericPolicy(policy)) { |
819 NOTREACHED(); | 804 NOTREACHED(); |
820 return 0; | 805 return 0; |
821 } | 806 } |
822 | 807 |
808 if (!g_sandboxed_process_starting_callback.Pointer()->is_null()) { | |
809 g_sandboxed_process_starting_callback.Pointer()->Run( | |
810 cmd_line, policy); | |
811 } | |
812 | |
823 if (browser_command_line.HasSwitch(switches::kEnableLogging)) { | 813 if (browser_command_line.HasSwitch(switches::kEnableLogging)) { |
824 // If stdout/stderr point to a Windows console, these calls will | 814 // If stdout/stderr point to a Windows console, these calls will |
825 // have no effect. | 815 // have no effect. |
826 policy->SetStdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE)); | 816 policy->SetStdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE)); |
827 policy->SetStderrHandle(GetStdHandle(STD_ERROR_HANDLE)); | 817 policy->SetStderrHandle(GetStdHandle(STD_ERROR_HANDLE)); |
828 } | 818 } |
829 | 819 |
830 TRACE_EVENT_BEGIN_ETW("StartProcessWithAccess::LAUNCHPROCESS", 0, 0); | 820 TRACE_EVENT_BEGIN_ETW("StartProcessWithAccess::LAUNCHPROCESS", 0, 0); |
831 | 821 |
832 result = g_broker_services->SpawnTarget( | 822 result = g_broker_services->SpawnTarget( |
833 cmd_line->GetProgram().value().c_str(), | 823 cmd_line->GetProgram().value().c_str(), |
834 cmd_line->GetCommandLineString().c_str(), | 824 cmd_line->GetCommandLineString().c_str(), |
835 policy, target.Receive()); | 825 policy, target.Receive()); |
836 policy->Release(); | 826 policy->Release(); |
837 | 827 |
838 TRACE_EVENT_END_ETW("StartProcessWithAccess::LAUNCHPROCESS", 0, 0); | 828 TRACE_EVENT_END_ETW("StartProcessWithAccess::LAUNCHPROCESS", 0, 0); |
839 | 829 |
840 if (sandbox::SBOX_ALL_OK != result) { | 830 if (sandbox::SBOX_ALL_OK != result) { |
841 DLOG(ERROR) << "Failed to launch process. Error: " << result; | 831 DLOG(ERROR) << "Failed to launch process. Error: " << result; |
842 return 0; | 832 return 0; |
843 } | 833 } |
844 | 834 |
845 #if !defined(NACL_WIN64) | 835 #if !defined(NACL_WIN64) |
846 // For Native Client sel_ldr processes on 32-bit Windows, reserve 1 GB of | 836 // For Native Client sel_ldr processes on 32-bit Windows, reserve 1 GB of |
cpu_(ooo_6.6-7.5)
2013/03/18 19:46:26
you want to add this as another callback after pro
jam
2013/03/18 19:50:19
yeah, this and other nacl stuff in this file will
| |
847 // address space to prevent later failure due to address space fragmentation | 837 // address space to prevent later failure due to address space fragmentation |
848 // from .dll loading. The NaCl process will attempt to locate this space by | 838 // from .dll loading. The NaCl process will attempt to locate this space by |
849 // scanning the address space using VirtualQuery. | 839 // scanning the address space using VirtualQuery. |
850 // TODO(bbudge) Handle the --no-sandbox case. | 840 // TODO(bbudge) Handle the --no-sandbox case. |
851 // http://code.google.com/p/nativeclient/issues/detail?id=2131 | 841 // http://code.google.com/p/nativeclient/issues/detail?id=2131 |
852 if (type == PROCESS_TYPE_NACL_LOADER) { | 842 if (type == PROCESS_TYPE_NACL_LOADER) { |
853 const SIZE_T kOneGigabyte = 1 << 30; | 843 const SIZE_T kOneGigabyte = 1 << 30; |
854 void* nacl_mem = VirtualAllocEx(target.process_handle(), | 844 void* nacl_mem = VirtualAllocEx(target.process_handle(), |
855 NULL, | 845 NULL, |
856 kOneGigabyte, | 846 kOneGigabyte, |
857 MEM_RESERVE, | 847 MEM_RESERVE, |
858 PAGE_NOACCESS); | 848 PAGE_NOACCESS); |
859 if (!nacl_mem) { | 849 if (!nacl_mem) { |
860 DLOG(WARNING) << "Failed to reserve address space for Native Client"; | 850 DLOG(WARNING) << "Failed to reserve address space for Native Client"; |
861 } | 851 } |
862 } | 852 } |
863 #endif // !defined(NACL_WIN64) | 853 #endif // !defined(NACL_WIN64) |
864 | 854 |
865 ResumeThread(target.thread_handle()); | 855 ResumeThread(target.thread_handle()); |
866 | 856 |
867 // Help the process a little. It can't start the debugger by itself if | 857 // Help the process a little. It can't start the debugger by itself if |
868 // the process is in a sandbox. | 858 // the process is in a sandbox. |
869 if (child_needs_help) | 859 if (child_needs_help) |
870 base::debug::SpawnDebuggerOnProcess(target.process_id()); | 860 base::debug::SpawnDebuggerOnProcess(target.process_id()); |
871 | 861 |
872 return target.TakeProcessHandle(); | 862 return target.TakeProcessHandle(); |
873 } | 863 } |
874 | 864 |
865 void SetSandboxedProcessStartingCallback( | |
866 const SandboxedProcessStartingCallback& callback) { | |
867 g_sandboxed_process_starting_callback.Get() = callback; | |
868 } | |
869 | |
875 bool BrokerDuplicateHandle(HANDLE source_handle, | 870 bool BrokerDuplicateHandle(HANDLE source_handle, |
876 DWORD target_process_id, | 871 DWORD target_process_id, |
877 HANDLE* target_handle, | 872 HANDLE* target_handle, |
878 DWORD desired_access, | 873 DWORD desired_access, |
879 DWORD options) { | 874 DWORD options) { |
880 // If our process is the target just duplicate the handle. | 875 // If our process is the target just duplicate the handle. |
881 if (::GetCurrentProcessId() == target_process_id) { | 876 if (::GetCurrentProcessId() == target_process_id) { |
882 return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, | 877 return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, |
883 ::GetCurrentProcess(), target_handle, | 878 ::GetCurrentProcess(), target_handle, |
884 desired_access, FALSE, options); | 879 desired_access, FALSE, options); |
(...skipping 19 matching lines...) Expand all Loading... | |
904 } | 899 } |
905 | 900 |
906 return false; | 901 return false; |
907 } | 902 } |
908 | 903 |
909 bool BrokerAddTargetPeer(HANDLE peer_process) { | 904 bool BrokerAddTargetPeer(HANDLE peer_process) { |
910 return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK; | 905 return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK; |
911 } | 906 } |
912 | 907 |
913 } // namespace content | 908 } // namespace content |
OLD | NEW |