OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/stringprintf.h" | |
6 #include "base/win/scoped_handle.h" | |
7 | |
8 #include "base/win/windows_version.h" | |
9 #include "sandbox/win/src/nt_internals.h" | |
10 #include "sandbox/win/src/process_mitigations.h" | |
11 #include "sandbox/win/src/sandbox.h" | |
12 #include "sandbox/win/src/sandbox_factory.h" | |
13 #include "sandbox/win/src/sandbox_utils.h" | |
14 #include "sandbox/win/src/target_services.h" | |
15 #include "sandbox/win/src/win_utils.h" | |
16 #include "sandbox/win/tests/common/controller.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 namespace { | |
20 | |
21 typedef BOOL (WINAPI *GetProcessDEPPolicyFunction)( | |
22 HANDLE process, | |
23 LPDWORD flags, | |
24 PBOOL permanent); | |
25 | |
26 typedef BOOL (WINAPI *GetProcessMitigationPolicyFunction)( | |
27 HANDLE process, | |
28 PROCESS_MITIGATION_POLICY mitigation_policy, | |
29 PVOID buffer, | |
30 SIZE_T length); | |
31 | |
32 GetProcessMitigationPolicyFunction get_process_mitigation_policy; | |
33 | |
34 bool CheckWin8DepPolicy() { | |
35 PROCESS_MITIGATION_DEP_POLICY policy; | |
36 if (!get_process_mitigation_policy(::GetCurrentProcess(), ProcessDEPPolicy, | |
37 &policy, sizeof(policy))) { | |
38 return false; | |
39 } | |
40 return policy.Enable && policy.Permanent; | |
41 } | |
42 | |
43 bool CheckWin8AslrPolicy() { | |
44 PROCESS_MITIGATION_ASLR_POLICY policy; | |
45 if (!get_process_mitigation_policy(::GetCurrentProcess(), ProcessASLRPolicy, | |
46 &policy, sizeof(policy))) { | |
47 return false; | |
48 } | |
49 return policy.EnableForceRelocateImages && policy.DisallowStrippedImages; | |
50 } | |
51 | |
52 bool CheckWin8StrictHandlePolicy() { | |
53 PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy; | |
54 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
55 ProcessStrictHandleCheckPolicy, | |
56 &policy, sizeof(policy))) { | |
57 return false; | |
58 } | |
59 return policy.RaiseExceptionOnInvalidHandleReference && | |
60 policy.HandleExceptionsPermanentlyEnabled; | |
61 } | |
62 | |
63 bool CheckWin8Win32CallPolicy() { | |
64 PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy; | |
65 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
66 ProcessSystemCallDisablePolicy, | |
67 &policy, sizeof(policy))) { | |
68 return false; | |
69 } | |
70 return policy.DisallowWin32kSystemCalls; | |
71 } | |
72 | |
73 bool CheckWin8DllExtensionPolicy() { | |
74 PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy; | |
75 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
76 ProcessExtensionPointDisablePolicy, | |
77 &policy, sizeof(policy))) { | |
78 return false; | |
79 } | |
80 return policy.DisableExtensionPoints; | |
81 } | |
82 | |
83 } // namespace | |
84 | |
85 namespace sandbox { | |
86 | |
87 SBOX_TESTS_COMMAND int CheckWin8(int argc, wchar_t **argv) { | |
88 get_process_mitigation_policy = | |
89 reinterpret_cast<GetProcessMitigationPolicyFunction>( | |
90 ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), | |
91 "GetProcessMitigationPolicy")); | |
92 | |
93 if (!get_process_mitigation_policy) | |
94 return SBOX_TEST_NOT_FOUND; | |
95 | |
96 if (!CheckWin8DepPolicy()) | |
97 return SBOX_TEST_FIRST_ERROR; | |
98 | |
99 if (!CheckWin8AslrPolicy()) | |
rvargas (doing something else)
2012/09/08 02:23:32
Did you considered just writing independent tests?
jschuh
2012/09/10 23:58:48
Yeah, but given the ever-increasing flakiness of t
rvargas (doing something else)
2012/09/13 19:15:26
That's the wrong way to look at it. The cause of f
| |
100 return SBOX_TEST_SECOND_ERROR; | |
101 | |
102 if (!CheckWin8StrictHandlePolicy()) | |
103 return SBOX_TEST_THIRD_ERROR; | |
104 | |
105 if (!CheckWin8Win32CallPolicy()) | |
106 return SBOX_TEST_FOURTH_ERROR; | |
107 | |
108 if (!CheckWin8DllExtensionPolicy()) | |
109 return SBOX_TEST_FIFTH_ERROR; | |
110 | |
111 return SBOX_TEST_SUCCEEDED; | |
112 } | |
113 | |
114 TEST(ProcessMitigationsTest, CheckWin8) { | |
115 if (base::win::GetVersion() < base::win::VERSION_WIN8) | |
116 return; | |
117 | |
118 TestRunner runner; | |
119 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
120 | |
121 EXPECT_EQ(policy->SetProcessMitigations( | |
122 TargetPolicy::MITIGATION_DEP | | |
123 TargetPolicy::MITIGATION_DEP_NO_ATL_THUNK | | |
124 TargetPolicy::MITIGATION_RELOCATE_IMAGE | | |
125 TargetPolicy::MITIGATION_RELOCATE_IMAGE_REQUIRED | | |
126 TargetPolicy::MITIGATION_EXTENSION_DLL_DISABLE), | |
127 SBOX_ALL_OK); | |
128 | |
129 EXPECT_EQ(policy->SetDelayedProcessMitigations( | |
130 TargetPolicy::MITIGATION_STRICT_HANDLE_CHECKS | | |
131 TargetPolicy::MITIGATION_WIN32K_DISABLE), | |
132 SBOX_ALL_OK); | |
133 | |
134 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8")); | |
135 } | |
136 | |
137 | |
138 SBOX_TESTS_COMMAND int CheckDep(int argc, wchar_t **argv) { | |
139 #ifndef _WIN64 // DEP is always enabled on 64-bit. | |
rvargas (doing something else)
2012/09/08 02:23:32
ditto
jschuh
2012/09/10 23:58:48
Done.
| |
140 GetProcessDEPPolicyFunction get_process_dep_policy = | |
141 reinterpret_cast<GetProcessDEPPolicyFunction>( | |
142 ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), | |
143 "GetProcessDEPPolicy")); | |
144 if (get_process_dep_policy) { | |
145 BOOL is_permanent = FALSE; | |
146 DWORD dep_flags = 0; | |
147 | |
148 if (!get_process_dep_policy(::GetCurrentProcess(), &dep_flags, | |
149 &is_permanent)) { | |
150 return SBOX_TEST_FIRST_ERROR; | |
151 } | |
152 | |
153 if (!(dep_flags & PROCESS_DEP_ENABLE) || !is_permanent) | |
154 return SBOX_TEST_SECOND_ERROR; | |
155 | |
156 } else { | |
157 NtQueryInformationProcessFunction query_information_process = NULL; | |
158 ResolveNTFunctionPtr("NtQueryInformationProcess", | |
159 &query_information_process); | |
160 if (!query_information_process) | |
161 return SBOX_TEST_NOT_FOUND; | |
162 | |
163 ULONG size = 0; | |
164 ULONG dep_flags = 0; | |
165 if (!SUCCEEDED(query_information_process(::GetCurrentProcess(), | |
166 ProcessExecuteFlags, &dep_flags, | |
167 sizeof(dep_flags), &size))) { | |
168 return SBOX_TEST_THIRD_ERROR; | |
169 } | |
170 | |
171 const int MEM_EXECUTE_OPTION_ENABLE = 1; | |
172 const int MEM_EXECUTE_OPTION_DISABLE = 2; | |
173 const int MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4; | |
174 const int MEM_EXECUTE_OPTION_PERMANENT = 8; | |
175 dep_flags &= 0xff; | |
176 | |
177 if (dep_flags != (MEM_EXECUTE_OPTION_DISABLE | | |
178 MEM_EXECUTE_OPTION_PERMANENT)) { | |
179 return SBOX_TEST_FOURTH_ERROR; | |
180 } | |
181 } | |
182 #endif | |
183 | |
184 return SBOX_TEST_SUCCEEDED; | |
185 } | |
186 | |
187 TEST(ProcessMitigationsTest, CheckDep) { | |
188 if (!IsXPSP2OrLater() || base::win::GetVersion() > base::win::VERSION_WIN7) | |
189 return; | |
190 | |
191 TestRunner runner; | |
192 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
193 | |
194 EXPECT_EQ(policy->SetProcessMitigations( | |
195 TargetPolicy::MITIGATION_DEP | | |
196 TargetPolicy::MITIGATION_DEP_NO_ATL_THUNK | | |
197 TargetPolicy::MITIGATION_SEHOP), | |
198 SBOX_ALL_OK); | |
199 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDep")); | |
200 } | |
201 | |
202 } // namespace sandbox | |
203 | |
OLD | NEW |