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 |