| 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 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 // Callers use CHECK macro to make sure we get the right stack. | 601 // Callers use CHECK macro to make sure we get the right stack. |
| 602 CheckDuplicateHandle(handle); | 602 CheckDuplicateHandle(handle); |
| 603 } | 603 } |
| 604 | 604 |
| 605 return TRUE; | 605 return TRUE; |
| 606 } | 606 } |
| 607 #endif | 607 #endif |
| 608 | 608 |
| 609 } // namespace | 609 } // namespace |
| 610 | 610 |
| 611 namespace sandbox { | 611 namespace content { |
| 612 | 612 |
| 613 bool InitBrokerServices(sandbox::BrokerServices* broker_services) { | 613 bool InitBrokerServices(sandbox::BrokerServices* broker_services) { |
| 614 // TODO(abarth): DCHECK(CalledOnValidThread()); | 614 // TODO(abarth): DCHECK(CalledOnValidThread()); |
| 615 // See <http://b/1287166>. | 615 // See <http://b/1287166>. |
| 616 DCHECK(broker_services); | 616 DCHECK(broker_services); |
| 617 DCHECK(!g_broker_services); | 617 DCHECK(!g_broker_services); |
| 618 sandbox::ResultCode result = broker_services->Init(); | 618 sandbox::ResultCode result = broker_services->Init(); |
| 619 g_broker_services = broker_services; | 619 g_broker_services = broker_services; |
| 620 | 620 |
| 621 // In non-official builds warn about dangerous uses of DuplicateHandle. | 621 // In non-official builds warn about dangerous uses of DuplicateHandle. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 634 if (result && (result != MAX_PATH)) { | 634 if (result && (result != MAX_PATH)) { |
| 635 ResolveNTFunctionPtr("NtQueryObject", &g_QueryObject); | 635 ResolveNTFunctionPtr("NtQueryObject", &g_QueryObject); |
| 636 g_iat_orig_duplicate_handle = ::DuplicateHandle; | 636 g_iat_orig_duplicate_handle = ::DuplicateHandle; |
| 637 g_iat_patch_duplicate_handle.Patch( | 637 g_iat_patch_duplicate_handle.Patch( |
| 638 module_name, "kernel32.dll", "DuplicateHandle", | 638 module_name, "kernel32.dll", "DuplicateHandle", |
| 639 DuplicateHandlePatch); | 639 DuplicateHandlePatch); |
| 640 } | 640 } |
| 641 } | 641 } |
| 642 #endif | 642 #endif |
| 643 | 643 |
| 644 return SBOX_ALL_OK == result; | 644 return sandbox::SBOX_ALL_OK == result; |
| 645 } | 645 } |
| 646 | 646 |
| 647 bool InitTargetServices(sandbox::TargetServices* target_services) { | 647 bool InitTargetServices(sandbox::TargetServices* target_services) { |
| 648 DCHECK(target_services); | 648 DCHECK(target_services); |
| 649 DCHECK(!g_target_services); | 649 DCHECK(!g_target_services); |
| 650 sandbox::ResultCode result = target_services->Init(); | 650 sandbox::ResultCode result = target_services->Init(); |
| 651 g_target_services = target_services; | 651 g_target_services = target_services; |
| 652 return SBOX_ALL_OK == result; | 652 return sandbox::SBOX_ALL_OK == result; |
| 653 } | 653 } |
| 654 | 654 |
| 655 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, | 655 base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line, |
| 656 const FilePath& exposed_dir) { | 656 const FilePath& exposed_dir) { |
| 657 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 657 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
| 658 content::ProcessType type; | 658 ProcessType type; |
| 659 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); | 659 std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 660 if (type_str == switches::kRendererProcess) { | 660 if (type_str == switches::kRendererProcess) { |
| 661 type = content::PROCESS_TYPE_RENDERER; | 661 type = PROCESS_TYPE_RENDERER; |
| 662 } else if (type_str == switches::kPluginProcess) { | 662 } else if (type_str == switches::kPluginProcess) { |
| 663 type = content::PROCESS_TYPE_PLUGIN; | 663 type = PROCESS_TYPE_PLUGIN; |
| 664 } else if (type_str == switches::kWorkerProcess) { | 664 } else if (type_str == switches::kWorkerProcess) { |
| 665 type = content::PROCESS_TYPE_WORKER; | 665 type = PROCESS_TYPE_WORKER; |
| 666 } else if (type_str == switches::kNaClLoaderProcess) { | 666 } else if (type_str == switches::kNaClLoaderProcess) { |
| 667 type = content::PROCESS_TYPE_NACL_LOADER; | 667 type = PROCESS_TYPE_NACL_LOADER; |
| 668 } else if (type_str == switches::kUtilityProcess) { | 668 } else if (type_str == switches::kUtilityProcess) { |
| 669 type = content::PROCESS_TYPE_UTILITY; | 669 type = PROCESS_TYPE_UTILITY; |
| 670 } else if (type_str == switches::kNaClBrokerProcess) { | 670 } else if (type_str == switches::kNaClBrokerProcess) { |
| 671 type = content::PROCESS_TYPE_NACL_BROKER; | 671 type = PROCESS_TYPE_NACL_BROKER; |
| 672 } else if (type_str == switches::kGpuProcess) { | 672 } else if (type_str == switches::kGpuProcess) { |
| 673 type = content::PROCESS_TYPE_GPU; | 673 type = PROCESS_TYPE_GPU; |
| 674 } else if (type_str == switches::kPpapiPluginProcess) { | 674 } else if (type_str == switches::kPpapiPluginProcess) { |
| 675 type = content::PROCESS_TYPE_PPAPI_PLUGIN; | 675 type = PROCESS_TYPE_PPAPI_PLUGIN; |
| 676 } else if (type_str == switches::kPpapiBrokerProcess) { | 676 } else if (type_str == switches::kPpapiBrokerProcess) { |
| 677 type = content::PROCESS_TYPE_PPAPI_BROKER; | 677 type = PROCESS_TYPE_PPAPI_BROKER; |
| 678 } else { | 678 } else { |
| 679 NOTREACHED(); | 679 NOTREACHED(); |
| 680 return 0; | 680 return 0; |
| 681 } | 681 } |
| 682 | 682 |
| 683 TRACE_EVENT_BEGIN_ETW("StartProcessWithAccess", 0, type_str); | 683 TRACE_EVENT_BEGIN_ETW("StartProcessWithAccess", 0, type_str); |
| 684 | 684 |
| 685 // To decide if the process is going to be sandboxed we have two cases. | 685 // To decide if the process is going to be sandboxed we have two cases. |
| 686 // First case: all process types except the nacl broker, and the plugin | 686 // First case: all process types except the nacl broker, and the plugin |
| 687 // process are sandboxed by default. | 687 // process are sandboxed by default. |
| 688 bool in_sandbox = | 688 bool in_sandbox = |
| 689 (type != content::PROCESS_TYPE_NACL_BROKER) && | 689 (type != PROCESS_TYPE_NACL_BROKER) && |
| 690 (type != content::PROCESS_TYPE_PLUGIN) && | 690 (type != PROCESS_TYPE_PLUGIN) && |
| 691 (type != content::PROCESS_TYPE_PPAPI_BROKER); | 691 (type != PROCESS_TYPE_PPAPI_BROKER); |
| 692 | 692 |
| 693 // If it is the GPU process then it can be disabled by a command line flag. | 693 // If it is the GPU process then it can be disabled by a command line flag. |
| 694 if ((type == content::PROCESS_TYPE_GPU) && | 694 if ((type == PROCESS_TYPE_GPU) && |
| 695 (cmd_line->HasSwitch(switches::kDisableGpuSandbox))) { | 695 (cmd_line->HasSwitch(switches::kDisableGpuSandbox))) { |
| 696 in_sandbox = false; | 696 in_sandbox = false; |
| 697 DVLOG(1) << "GPU sandbox is disabled"; | 697 DVLOG(1) << "GPU sandbox is disabled"; |
| 698 } | 698 } |
| 699 | 699 |
| 700 if (browser_command_line.HasSwitch(switches::kNoSandbox) || | 700 if (browser_command_line.HasSwitch(switches::kNoSandbox) || |
| 701 cmd_line->HasSwitch(switches::kNoSandbox)) { | 701 cmd_line->HasSwitch(switches::kNoSandbox)) { |
| 702 // The user or the caller has explicity opted-out from all sandboxing. | 702 // The user or the caller has explicity opted-out from all sandboxing. |
| 703 in_sandbox = false; | 703 in_sandbox = false; |
| 704 } | 704 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 base::ProcessHandle process = 0; | 741 base::ProcessHandle process = 0; |
| 742 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); | 742 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); |
| 743 g_broker_services->AddTargetPeer(process); | 743 g_broker_services->AddTargetPeer(process); |
| 744 return process; | 744 return process; |
| 745 } | 745 } |
| 746 | 746 |
| 747 base::win::ScopedProcessInformation target; | 747 base::win::ScopedProcessInformation target; |
| 748 sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy(); | 748 sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy(); |
| 749 | 749 |
| 750 // TODO(jschuh): Make NaCl work with DEP and SEHOP. crbug.com/147752 | 750 // TODO(jschuh): Make NaCl work with DEP and SEHOP. crbug.com/147752 |
| 751 sandbox::MitigationFlags mitigations = MITIGATION_HEAP_TERMINATE | | 751 sandbox::MitigationFlags mitigations = sandbox::MITIGATION_HEAP_TERMINATE | |
| 752 MITIGATION_BOTTOM_UP_ASLR | | 752 sandbox::MITIGATION_BOTTOM_UP_ASLR | |
| 753 MITIGATION_HIGH_ENTROPY_ASLR; | 753 sandbox::MITIGATION_HIGH_ENTROPY_ASLR; |
| 754 #if !defined(NACL_WIN64) | 754 #if !defined(NACL_WIN64) |
| 755 mitigations |= MITIGATION_DEP | | 755 mitigations |= sandbox::MITIGATION_DEP | |
| 756 MITIGATION_DEP_NO_ATL_THUNK | | 756 sandbox::MITIGATION_DEP_NO_ATL_THUNK | |
| 757 MITIGATION_SEHOP; | 757 sandbox::MITIGATION_SEHOP; |
| 758 #if defined(NDEBUG) | 758 #if defined(NDEBUG) |
| 759 mitigations |= MITIGATION_RELOCATE_IMAGE | | 759 mitigations |= sandbox::MITIGATION_RELOCATE_IMAGE | |
| 760 MITIGATION_RELOCATE_IMAGE_REQUIRED; | 760 sandbox::MITIGATION_RELOCATE_IMAGE_REQUIRED; |
| 761 #endif | 761 #endif |
| 762 #endif | 762 #endif |
| 763 | 763 |
| 764 if (policy->SetProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK) | 764 if (policy->SetProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK) |
| 765 return 0; | 765 return 0; |
| 766 | 766 |
| 767 mitigations = MITIGATION_STRICT_HANDLE_CHECKS | | 767 mitigations = sandbox::MITIGATION_STRICT_HANDLE_CHECKS | |
| 768 MITIGATION_DLL_SEARCH_ORDER; | 768 sandbox::MITIGATION_DLL_SEARCH_ORDER; |
| 769 #if defined(NACL_WIN64) | 769 #if defined(NACL_WIN64) |
| 770 mitigations |= MITIGATION_DEP | | 770 mitigations |= sandbox::MITIGATION_DEP | |
| 771 MITIGATION_DEP_NO_ATL_THUNK; | 771 sandbox::MITIGATION_DEP_NO_ATL_THUNK; |
| 772 #endif | 772 #endif |
| 773 | 773 |
| 774 if (policy->SetDelayedProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK) | 774 if (policy->SetDelayedProcessMitigations(mitigations) != sandbox::SBOX_ALL_OK) |
| 775 return 0; | 775 return 0; |
| 776 | 776 |
| 777 SetJobLevel(*cmd_line, JOB_LOCKDOWN, 0, policy); | 777 SetJobLevel(*cmd_line, sandbox::JOB_LOCKDOWN, 0, policy); |
| 778 | 778 |
| 779 if (type == content::PROCESS_TYPE_GPU) { | 779 if (type == PROCESS_TYPE_GPU) { |
| 780 if (!AddPolicyForGPU(cmd_line, policy)) | 780 if (!AddPolicyForGPU(cmd_line, policy)) |
| 781 return 0; | 781 return 0; |
| 782 } else { | 782 } else { |
| 783 if (!AddPolicyForRenderer(policy)) | 783 if (!AddPolicyForRenderer(policy)) |
| 784 return 0; | 784 return 0; |
| 785 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. | 785 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. |
| 786 // Just have to figure out what needs to be warmed up first. | 786 // Just have to figure out what needs to be warmed up first. |
| 787 if (type == content::PROCESS_TYPE_RENDERER || | 787 if (type == PROCESS_TYPE_RENDERER || |
| 788 type == content::PROCESS_TYPE_WORKER) { | 788 type == PROCESS_TYPE_WORKER) { |
| 789 AddBaseHandleClosePolicy(policy); | 789 AddBaseHandleClosePolicy(policy); |
| 790 } | 790 } |
| 791 | 791 |
| 792 // Pepper uses the renderer's policy, whith some tweaks. | 792 // Pepper uses the renderer's policy, whith some tweaks. |
| 793 if (cmd_line->HasSwitch(switches::kGuestRenderer) || | 793 if (cmd_line->HasSwitch(switches::kGuestRenderer) || |
| 794 type == content::PROCESS_TYPE_PPAPI_PLUGIN) { | 794 type == PROCESS_TYPE_PPAPI_PLUGIN) { |
| 795 if (!AddPolicyForPepperPlugin(policy)) | 795 if (!AddPolicyForPepperPlugin(policy)) |
| 796 return 0; | 796 return 0; |
| 797 } | 797 } |
| 798 | 798 |
| 799 | 799 |
| 800 if (type_str != switches::kRendererProcess) { | 800 if (type_str != switches::kRendererProcess) { |
| 801 // Hack for Google Desktop crash. Trick GD into not injecting its DLL into | 801 // Hack for Google Desktop crash. Trick GD into not injecting its DLL into |
| 802 // this subprocess. See | 802 // this subprocess. See |
| 803 // http://code.google.com/p/chromium/issues/detail?id=25580 | 803 // http://code.google.com/p/chromium/issues/detail?id=25580 |
| 804 cmd_line->AppendSwitchASCII("ignored", " --type=renderer "); | 804 cmd_line->AppendSwitchASCII("ignored", " --type=renderer "); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 return 0; | 841 return 0; |
| 842 } | 842 } |
| 843 | 843 |
| 844 #if !defined(NACL_WIN64) | 844 #if !defined(NACL_WIN64) |
| 845 // For Native Client sel_ldr processes on 32-bit Windows, reserve 1 GB of | 845 // For Native Client sel_ldr processes on 32-bit Windows, reserve 1 GB of |
| 846 // address space to prevent later failure due to address space fragmentation | 846 // address space to prevent later failure due to address space fragmentation |
| 847 // from .dll loading. The NaCl process will attempt to locate this space by | 847 // from .dll loading. The NaCl process will attempt to locate this space by |
| 848 // scanning the address space using VirtualQuery. | 848 // scanning the address space using VirtualQuery. |
| 849 // TODO(bbudge) Handle the --no-sandbox case. | 849 // TODO(bbudge) Handle the --no-sandbox case. |
| 850 // http://code.google.com/p/nativeclient/issues/detail?id=2131 | 850 // http://code.google.com/p/nativeclient/issues/detail?id=2131 |
| 851 if (type == content::PROCESS_TYPE_NACL_LOADER) { | 851 if (type == PROCESS_TYPE_NACL_LOADER) { |
| 852 const SIZE_T kOneGigabyte = 1 << 30; | 852 const SIZE_T kOneGigabyte = 1 << 30; |
| 853 void* nacl_mem = VirtualAllocEx(target.process_handle(), | 853 void* nacl_mem = VirtualAllocEx(target.process_handle(), |
| 854 NULL, | 854 NULL, |
| 855 kOneGigabyte, | 855 kOneGigabyte, |
| 856 MEM_RESERVE, | 856 MEM_RESERVE, |
| 857 PAGE_NOACCESS); | 857 PAGE_NOACCESS); |
| 858 if (!nacl_mem) { | 858 if (!nacl_mem) { |
| 859 DLOG(WARNING) << "Failed to reserve address space for Native Client"; | 859 DLOG(WARNING) << "Failed to reserve address space for Native Client"; |
| 860 } | 860 } |
| 861 } | 861 } |
| 862 #endif // !defined(NACL_WIN64) | 862 #endif // !defined(NACL_WIN64) |
| 863 | 863 |
| 864 ResumeThread(target.thread_handle()); | 864 ResumeThread(target.thread_handle()); |
| 865 | 865 |
| 866 // Help the process a little. It can't start the debugger by itself if | 866 // Help the process a little. It can't start the debugger by itself if |
| 867 // the process is in a sandbox. | 867 // the process is in a sandbox. |
| 868 if (child_needs_help) | 868 if (child_needs_help) |
| 869 base::debug::SpawnDebuggerOnProcess(target.process_id()); | 869 base::debug::SpawnDebuggerOnProcess(target.process_id()); |
| 870 | 870 |
| 871 return target.TakeProcessHandle(); | 871 return target.TakeProcessHandle(); |
| 872 } | 872 } |
| 873 | 873 |
| 874 } // namespace sandbox | |
| 875 | |
| 876 namespace content { | |
| 877 | |
| 878 bool BrokerDuplicateHandle(HANDLE source_handle, | 874 bool BrokerDuplicateHandle(HANDLE source_handle, |
| 879 DWORD target_process_id, | 875 DWORD target_process_id, |
| 880 HANDLE* target_handle, | 876 HANDLE* target_handle, |
| 881 DWORD desired_access, | 877 DWORD desired_access, |
| 882 DWORD options) { | 878 DWORD options) { |
| 883 // If our process is the target just duplicate the handle. | 879 // If our process is the target just duplicate the handle. |
| 884 if (::GetCurrentProcessId() == target_process_id) { | 880 if (::GetCurrentProcessId() == target_process_id) { |
| 885 return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, | 881 return !!::DuplicateHandle(::GetCurrentProcess(), source_handle, |
| 886 ::GetCurrentProcess(), target_handle, | 882 ::GetCurrentProcess(), target_handle, |
| 887 desired_access, FALSE, options); | 883 desired_access, FALSE, options); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 906 desired_access, FALSE, options); | 902 desired_access, FALSE, options); |
| 907 } | 903 } |
| 908 | 904 |
| 909 return false; | 905 return false; |
| 910 } | 906 } |
| 911 | 907 |
| 912 bool BrokerAddTargetPeer(HANDLE peer_process) { | 908 bool BrokerAddTargetPeer(HANDLE peer_process) { |
| 913 return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK; | 909 return g_broker_services->AddTargetPeer(peer_process) == sandbox::SBOX_ALL_OK; |
| 914 } | 910 } |
| 915 | 911 |
| 916 base::ProcessHandle StartProcessWithAccess( | |
| 917 CommandLine* cmd_line, | |
| 918 const FilePath& exposed_dir) { | |
| 919 return sandbox::StartProcessWithAccess(cmd_line, exposed_dir); | |
| 920 } | |
| 921 | |
| 922 } // namespace content | 912 } // namespace content |
| OLD | NEW |