1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/process_mitigations_test.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,207 @@ 1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/strings/stringprintf.h" 1.9 +#include "base/win/scoped_handle.h" 1.10 + 1.11 +#include "base/win/windows_version.h" 1.12 +#include "sandbox/win/src/nt_internals.h" 1.13 +#include "sandbox/win/src/process_mitigations.h" 1.14 +#include "sandbox/win/src/sandbox.h" 1.15 +#include "sandbox/win/src/sandbox_factory.h" 1.16 +#include "sandbox/win/src/sandbox_utils.h" 1.17 +#include "sandbox/win/src/target_services.h" 1.18 +#include "sandbox/win/src/win_utils.h" 1.19 +#include "sandbox/win/tests/common/controller.h" 1.20 +#include "testing/gtest/include/gtest/gtest.h" 1.21 + 1.22 +namespace { 1.23 + 1.24 +typedef BOOL (WINAPI *GetProcessDEPPolicyFunction)( 1.25 + HANDLE process, 1.26 + LPDWORD flags, 1.27 + PBOOL permanent); 1.28 + 1.29 +typedef BOOL (WINAPI *GetProcessMitigationPolicyFunction)( 1.30 + HANDLE process, 1.31 + PROCESS_MITIGATION_POLICY mitigation_policy, 1.32 + PVOID buffer, 1.33 + SIZE_T length); 1.34 + 1.35 +GetProcessMitigationPolicyFunction get_process_mitigation_policy; 1.36 + 1.37 +bool CheckWin8DepPolicy() { 1.38 + PROCESS_MITIGATION_DEP_POLICY policy; 1.39 + if (!get_process_mitigation_policy(::GetCurrentProcess(), ProcessDEPPolicy, 1.40 + &policy, sizeof(policy))) { 1.41 + return false; 1.42 + } 1.43 + return policy.Enable && policy.Permanent; 1.44 +} 1.45 + 1.46 +bool CheckWin8AslrPolicy() { 1.47 + PROCESS_MITIGATION_ASLR_POLICY policy; 1.48 + if (!get_process_mitigation_policy(::GetCurrentProcess(), ProcessASLRPolicy, 1.49 + &policy, sizeof(policy))) { 1.50 + return false; 1.51 + } 1.52 + return policy.EnableForceRelocateImages && policy.DisallowStrippedImages; 1.53 +} 1.54 + 1.55 +bool CheckWin8StrictHandlePolicy() { 1.56 + PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy; 1.57 + if (!get_process_mitigation_policy(::GetCurrentProcess(), 1.58 + ProcessStrictHandleCheckPolicy, 1.59 + &policy, sizeof(policy))) { 1.60 + return false; 1.61 + } 1.62 + return policy.RaiseExceptionOnInvalidHandleReference && 1.63 + policy.HandleExceptionsPermanentlyEnabled; 1.64 +} 1.65 + 1.66 +bool CheckWin8Win32CallPolicy() { 1.67 + PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy; 1.68 + if (!get_process_mitigation_policy(::GetCurrentProcess(), 1.69 + ProcessSystemCallDisablePolicy, 1.70 + &policy, sizeof(policy))) { 1.71 + return false; 1.72 + } 1.73 + return policy.DisallowWin32kSystemCalls; 1.74 +} 1.75 + 1.76 +bool CheckWin8DllExtensionPolicy() { 1.77 + PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy; 1.78 + if (!get_process_mitigation_policy(::GetCurrentProcess(), 1.79 + ProcessExtensionPointDisablePolicy, 1.80 + &policy, sizeof(policy))) { 1.81 + return false; 1.82 + } 1.83 + return policy.DisableExtensionPoints; 1.84 +} 1.85 + 1.86 +} // namespace 1.87 + 1.88 +namespace sandbox { 1.89 + 1.90 +SBOX_TESTS_COMMAND int CheckWin8(int argc, wchar_t **argv) { 1.91 + get_process_mitigation_policy = 1.92 + reinterpret_cast<GetProcessMitigationPolicyFunction>( 1.93 + ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), 1.94 + "GetProcessMitigationPolicy")); 1.95 + 1.96 + if (!get_process_mitigation_policy) 1.97 + return SBOX_TEST_NOT_FOUND; 1.98 + 1.99 + if (!CheckWin8DepPolicy()) 1.100 + return SBOX_TEST_FIRST_ERROR; 1.101 + 1.102 +#if defined(NDEBUG) // ASLR cannot be forced in debug builds. 1.103 + if (!CheckWin8AslrPolicy()) 1.104 + return SBOX_TEST_SECOND_ERROR; 1.105 +#endif 1.106 + 1.107 + if (!CheckWin8StrictHandlePolicy()) 1.108 + return SBOX_TEST_THIRD_ERROR; 1.109 + 1.110 + if (!CheckWin8Win32CallPolicy()) 1.111 + return SBOX_TEST_FOURTH_ERROR; 1.112 + 1.113 + if (!CheckWin8DllExtensionPolicy()) 1.114 + return SBOX_TEST_FIFTH_ERROR; 1.115 + 1.116 + return SBOX_TEST_SUCCEEDED; 1.117 +} 1.118 + 1.119 +TEST(ProcessMitigationsTest, CheckWin8) { 1.120 + if (base::win::GetVersion() < base::win::VERSION_WIN8) 1.121 + return; 1.122 + 1.123 + TestRunner runner; 1.124 + sandbox::TargetPolicy* policy = runner.GetPolicy(); 1.125 + 1.126 + sandbox::MitigationFlags mitigations = MITIGATION_DEP | 1.127 + MITIGATION_DEP_NO_ATL_THUNK | 1.128 + MITIGATION_EXTENSION_DLL_DISABLE; 1.129 +#if defined(NDEBUG) // ASLR cannot be forced in debug builds. 1.130 + mitigations |= MITIGATION_RELOCATE_IMAGE | 1.131 + MITIGATION_RELOCATE_IMAGE_REQUIRED; 1.132 +#endif 1.133 + 1.134 + EXPECT_EQ(policy->SetProcessMitigations(mitigations), SBOX_ALL_OK); 1.135 + 1.136 + mitigations |= MITIGATION_STRICT_HANDLE_CHECKS | 1.137 + MITIGATION_WIN32K_DISABLE; 1.138 + 1.139 + EXPECT_EQ(policy->SetDelayedProcessMitigations(mitigations), SBOX_ALL_OK); 1.140 + 1.141 + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8")); 1.142 +} 1.143 + 1.144 + 1.145 +SBOX_TESTS_COMMAND int CheckDep(int argc, wchar_t **argv) { 1.146 + GetProcessDEPPolicyFunction get_process_dep_policy = 1.147 + reinterpret_cast<GetProcessDEPPolicyFunction>( 1.148 + ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), 1.149 + "GetProcessDEPPolicy")); 1.150 + if (get_process_dep_policy) { 1.151 + BOOL is_permanent = FALSE; 1.152 + DWORD dep_flags = 0; 1.153 + 1.154 + if (!get_process_dep_policy(::GetCurrentProcess(), &dep_flags, 1.155 + &is_permanent)) { 1.156 + return SBOX_TEST_FIRST_ERROR; 1.157 + } 1.158 + 1.159 + if (!(dep_flags & PROCESS_DEP_ENABLE) || !is_permanent) 1.160 + return SBOX_TEST_SECOND_ERROR; 1.161 + 1.162 + } else { 1.163 + NtQueryInformationProcessFunction query_information_process = NULL; 1.164 + ResolveNTFunctionPtr("NtQueryInformationProcess", 1.165 + &query_information_process); 1.166 + if (!query_information_process) 1.167 + return SBOX_TEST_NOT_FOUND; 1.168 + 1.169 + ULONG size = 0; 1.170 + ULONG dep_flags = 0; 1.171 + if (!SUCCEEDED(query_information_process(::GetCurrentProcess(), 1.172 + ProcessExecuteFlags, &dep_flags, 1.173 + sizeof(dep_flags), &size))) { 1.174 + return SBOX_TEST_THIRD_ERROR; 1.175 + } 1.176 + 1.177 + const int MEM_EXECUTE_OPTION_ENABLE = 1; 1.178 + const int MEM_EXECUTE_OPTION_DISABLE = 2; 1.179 + const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4; 1.180 + const int MEM_EXECUTE_OPTION_PERMANENT = 8; 1.181 + dep_flags &= 0xff; 1.182 + 1.183 + if (dep_flags != (MEM_EXECUTE_OPTION_DISABLE | 1.184 + MEM_EXECUTE_OPTION_PERMANENT)) { 1.185 + return SBOX_TEST_FOURTH_ERROR; 1.186 + } 1.187 + } 1.188 + 1.189 + return SBOX_TEST_SUCCEEDED; 1.190 +} 1.191 + 1.192 +#if !defined(_WIN64) // DEP is always enabled on 64-bit. 1.193 +TEST(ProcessMitigationsTest, CheckDep) { 1.194 + if (!IsXPSP2OrLater() || base::win::GetVersion() > base::win::VERSION_WIN7) 1.195 + return; 1.196 + 1.197 + TestRunner runner; 1.198 + sandbox::TargetPolicy* policy = runner.GetPolicy(); 1.199 + 1.200 + EXPECT_EQ(policy->SetProcessMitigations( 1.201 + MITIGATION_DEP | 1.202 + MITIGATION_DEP_NO_ATL_THUNK | 1.203 + MITIGATION_SEHOP), 1.204 + SBOX_ALL_OK); 1.205 + EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDep")); 1.206 +} 1.207 +#endif 1.208 + 1.209 +} // namespace sandbox 1.210 +