Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: sandbox/win/src/process_mitigations_test.cc

Issue 1835003003: [Windows Sandbox] MITIGATION_EXTENSION_POINT_DISABLE support for children. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: GN fix (thanks Bruce) Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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 "sandbox/win/src/process_mitigations.h"
6
7 #include <psapi.h>
8
9 #include <chrono>
10 #include <thread>
dcheng 2016/04/03 23:30:01 Btw, I hate to the bearer of bad news but both <ch
Will Harris 2016/04/04 00:16:41 yes I noticed that too, suggested using base::Plat
penny 2016/04/11 22:11:58 Done.
11
12 #include "base/command_line.h"
5 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
6 #include "base/files/scoped_temp_dir.h" 14 #include "base/files/scoped_temp_dir.h"
15 #include "base/memory/free_deleter.h"
7 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
8 #include "base/path_service.h" 17 #include "base/path_service.h"
9 #include "base/process/launch.h" 18 #include "base/process/launch.h"
10 #include "base/strings/stringprintf.h" 19 #include "base/win/registry.h"
11 #include "base/win/scoped_handle.h" 20 #include "base/win/scoped_handle.h"
21 #include "base/win/startup_information.h"
22 #include "base/win/win_util.h"
12 #include "base/win/windows_version.h" 23 #include "base/win/windows_version.h"
13 #include "sandbox/win/src/nt_internals.h" 24 #include "sandbox/win/src/nt_internals.h"
14 #include "sandbox/win/src/process_mitigations.h"
15 #include "sandbox/win/src/sandbox.h" 25 #include "sandbox/win/src/sandbox.h"
16 #include "sandbox/win/src/sandbox_factory.h" 26 #include "sandbox/win/src/sandbox_factory.h"
17 #include "sandbox/win/src/target_services.h" 27 #include "sandbox/win/src/target_services.h"
18 #include "sandbox/win/src/win_utils.h"
19 #include "sandbox/win/tests/common/controller.h" 28 #include "sandbox/win/tests/common/controller.h"
20 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
21 30
22 namespace { 31 namespace {
23 32
24 // API defined in winbase.h. 33 // API defined in winbase.h.
25 typedef decltype(GetProcessDEPPolicy)* GetProcessDEPPolicyFunction; 34 typedef decltype(GetProcessDEPPolicy)* GetProcessDEPPolicyFunction;
26 35
27 // API defined in processthreadsapi.h. 36 // API defined in processthreadsapi.h.
28 typedef decltype( 37 typedef decltype(
29 GetProcessMitigationPolicy)* GetProcessMitigationPolicyFunction; 38 GetProcessMitigationPolicy)* GetProcessMitigationPolicyFunction;
30 GetProcessMitigationPolicyFunction get_process_mitigation_policy; 39 GetProcessMitigationPolicyFunction get_process_mitigation_policy;
31 40
32 // APIs defined in wingdi.h. 41 // APIs defined in wingdi.h.
33 typedef decltype(AddFontMemResourceEx)* AddFontMemResourceExFunction; 42 typedef decltype(AddFontMemResourceEx)* AddFontMemResourceExFunction;
34 typedef decltype(RemoveFontMemResourceEx)* RemoveFontMemResourceExFunction; 43 typedef decltype(RemoveFontMemResourceEx)* RemoveFontMemResourceExFunction;
35 44
45 // WinProc event name for synchronization.
46 const wchar_t* winproc_event = L"ChromeExtensionTestEvent";
47 DWORD event_max_wait_ms = 3 * 1000;
48
36 #if !defined(_WIN64) 49 #if !defined(_WIN64)
37 bool CheckWin8DepPolicy() { 50 bool CheckWin8DepPolicy() {
38 PROCESS_MITIGATION_DEP_POLICY policy = {}; 51 PROCESS_MITIGATION_DEP_POLICY policy = {};
39 if (!get_process_mitigation_policy(::GetCurrentProcess(), ProcessDEPPolicy, 52 if (!get_process_mitigation_policy(::GetCurrentProcess(), ProcessDEPPolicy,
40 &policy, sizeof(policy))) { 53 &policy, sizeof(policy))) {
41 return false; 54 return false;
42 } 55 }
43 return policy.Enable && policy.Permanent; 56 return policy.Enable && policy.Permanent;
44 } 57 }
45 #endif // !defined(_WIN64) 58 #endif // !defined(_WIN64)
(...skipping 23 matching lines...) Expand all
69 bool CheckWin8Win32CallPolicy() { 82 bool CheckWin8Win32CallPolicy() {
70 PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {}; 83 PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {};
71 if (!get_process_mitigation_policy(::GetCurrentProcess(), 84 if (!get_process_mitigation_policy(::GetCurrentProcess(),
72 ProcessSystemCallDisablePolicy, 85 ProcessSystemCallDisablePolicy,
73 &policy, sizeof(policy))) { 86 &policy, sizeof(policy))) {
74 return false; 87 return false;
75 } 88 }
76 return policy.DisallowWin32kSystemCalls; 89 return policy.DisallowWin32kSystemCalls;
77 } 90 }
78 91
79 bool CheckWin8DllExtensionPolicy() { 92 bool CheckWin8ExtensionPointPolicy() {
80 PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy = {}; 93 PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy = {};
81 if (!get_process_mitigation_policy(::GetCurrentProcess(), 94 if (!get_process_mitigation_policy(::GetCurrentProcess(),
82 ProcessExtensionPointDisablePolicy, 95 ProcessExtensionPointDisablePolicy,
83 &policy, sizeof(policy))) { 96 &policy, sizeof(policy))) {
84 return false; 97 return false;
85 } 98 }
86 return policy.DisableExtensionPoints; 99 return policy.DisableExtensionPoints;
87 } 100 }
88 101
89 bool CheckWin10FontPolicy() { 102 bool CheckWin10FontPolicy() {
90 PROCESS_MITIGATION_FONT_DISABLE_POLICY policy = {}; 103 PROCESS_MITIGATION_FONT_DISABLE_POLICY policy = {};
91 if (!get_process_mitigation_policy(::GetCurrentProcess(), 104 if (!get_process_mitigation_policy(::GetCurrentProcess(),
92 ProcessFontDisablePolicy, &policy, 105 ProcessFontDisablePolicy, &policy,
93 sizeof(policy))) { 106 sizeof(policy))) {
94 return false; 107 return false;
95 } 108 }
96 return policy.DisableNonSystemFonts; 109 return policy.DisableNonSystemFonts;
97 } 110 }
98 111
99 bool CheckWin10ImageLoadNoRemotePolicy() { 112 bool CheckWin10ImageLoadNoRemotePolicy() {
100 PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {}; 113 PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {};
101 if (!get_process_mitigation_policy(::GetCurrentProcess(), 114 if (!get_process_mitigation_policy(::GetCurrentProcess(),
102 ProcessImageLoadPolicy, &policy, 115 ProcessImageLoadPolicy, &policy,
103 sizeof(policy))) { 116 sizeof(policy))) {
104 return false; 117 return false;
105 } 118 }
106 return policy.NoRemoteImages; 119 return policy.NoRemoteImages;
107 } 120 }
108 121
122 // Spawn our Windows process (with or without mitigation enabled).
Will Harris 2016/04/04 00:15:08 style nit, feel free to ignore, but prefer not to
penny 2016/04/11 22:11:59 Done.
123 void SpawnWinProc(PROCESS_INFORMATION* pi, bool success_test, HANDLE* event) {
124 base::win::StartupInformation startup_info;
125 DWORD creation_flags = 0;
126
127 if (!success_test) {
128 DWORD64 flags =
129 PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE_ALWAYS_ON;
130 // This test only runs on >= Win8, so I don't have to worry about
131 // illegal 64-bit flags on 32-bit <= Win7.
132 size_t flags_size = sizeof(flags);
133
134 EXPECT_TRUE(startup_info.InitializeProcThreadAttributeList(1));
135 EXPECT_TRUE(startup_info.UpdateProcThreadAttribute(
136 PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &flags, flags_size));
137 creation_flags = EXTENDED_STARTUPINFO_PRESENT;
138 }
139
140 std::wstring cmd_line = L"sbox_integration_test_win_proc.exe ";
141 scoped_ptr<wchar_t, base::FreeDeleter> cmd_writeable(
142 ::wcsdup(cmd_line.c_str()));
143
144 EXPECT_TRUE(::CreateProcessW(NULL, cmd_writeable.get(), NULL, NULL, FALSE,
145 creation_flags, NULL, NULL,
146 startup_info.startup_info(), pi));
147 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(*event, event_max_wait_ms));
148
149 return;
150 }
151
152 //------------------------------------------------------------------------------
153 // 1. Spawn our Windows process (with or without mitigation enabled).
154 // 2. Load our hook Dll locally.
155 // 3. Start the hook (for our WinProc or globally).
156 // 4. Send a keystroke event.
157 // 5. Ask the hook Dll if it received a hook callback.
158 // 6. Cleanup the hooking.
159 // 7. Signal our Windows process to shutdown.
160 //
161 // Do NOT use any ASSERTs in this function. Cleanup required.
162 //------------------------------------------------------------------------------
163
164 typedef BOOL (*WasHookCalledFunction)();
165
166 void TestWin8ExtensionPointHookWrapper(bool is_success_test, bool global_hook) {
167 HMODULE dll = NULL;
Will Harris 2016/04/04 00:15:09 chromium style is to declare variables just before
penny 2016/04/11 22:11:58 Done.
168 HHOOK hook = NULL;
169 HOOKPROC hook_proc = NULL;
170 WasHookCalledFunction WasHookCalled = NULL;
171 PROCESS_INFORMATION proc_info = {};
172
173 // 1. Spawn WinProc.
174 HANDLE event = ::CreateEventW(NULL, FALSE, FALSE, winproc_event);
175 EXPECT_TRUE(event != NULL && event != INVALID_HANDLE_VALUE);
176 SpawnWinProc(&proc_info, is_success_test, &event);
177
178 // 2. Load the hook DLL.
179 dll = ::LoadLibraryW(L"sbox_integration_test_hook_dll.dll");
Will Harris 2016/04/04 00:15:08 prefer ScopedNativeLibrary here rather than LoadLi
penny 2016/04/11 22:11:58 Done.
180 EXPECT_TRUE(dll);
181
182 hook_proc = reinterpret_cast<HOOKPROC>(::GetProcAddress(dll, "HookProc"));
183 WasHookCalled = reinterpret_cast<WasHookCalledFunction>(
184 ::GetProcAddress(dll, "WasHookCalled"));
Will Harris 2016/04/04 00:15:08 you could #define WasHookCalled in a .h file for y
penny 2016/04/11 22:11:59 Acknowledged. I've created a new common.h file wi
185 EXPECT_TRUE(hook_proc && WasHookCalled);
186
187 // 3. Try installing the hook (either on our remote target thread,
188 // or globally).
189 DWORD target = 0;
190 if (!global_hook)
191 target = proc_info.dwThreadId;
192 hook = ::SetWindowsHookExW(WH_KEYBOARD, hook_proc, dll, target);
193 EXPECT_TRUE(hook);
194
195 // 4. Inject a keyboard event.
196
197 // Note: that PostThreadMessage and SendMessage APIs will not deliver
198 // a keystroke in such a way that triggers a "legitimate" hook.
199 // Have to use targetless SendInput or keybd_event. The latter is
200 // less code and easier to work with.
201 keybd_event(VkKeyScan(L'A'), 0, 0, 0);
202 std::this_thread::sleep_for(std::chrono::milliseconds(500));
Will Harris 2016/04/04 00:15:09 base::PlatformThread::Sleep() and base::TimeDelta
penny 2016/04/11 22:11:58 Done.
203 keybd_event(VkKeyScan(L'A'), 0, KEYEVENTF_KEYUP, 0);
204
205 // Give it a chance...
206 std::this_thread::sleep_for(std::chrono::seconds(1));
207
208 // 5. Did our hook get hit? Did we expect it to?
209 if (global_hook)
210 EXPECT_EQ((is_success_test ? TRUE : FALSE), WasHookCalled());
Will Harris 2016/04/04 00:15:08 true and false not TRUE and FALSE
penny 2016/04/11 22:11:59 Done. The function WasHookCalled() was actually d
211 else
212 // ***IMPORTANT: when targeting a specific thread id, the
213 // PROCESS_CREATION_MITIGATION_POLICY_EXTENSION_POINT_DISABLE
214 // mitigation does NOT disable the hook API. It ONLY
215 // stops global hooks from running in your process. Hence,
216 // we expect the hook to have hit (TRUE) even in the "failure"
217 // case for a non-global/targetted hook.
218 EXPECT_EQ((is_success_test ? TRUE : TRUE), WasHookCalled());
219
220 // 6. Rip it all down.
221 if (hook)
222 EXPECT_TRUE(::UnhookWindowsHookEx(hook));
223 if (dll)
224 EXPECT_TRUE(::FreeLibrary(dll));
Will Harris 2016/04/04 00:15:08 this can go if you are using ScopedNativeLibrary
penny 2016/04/11 22:11:59 Done.
225
226 // 7. Trigger shutdown of WinProc.
227 if (::PostThreadMessageW(proc_info.dwThreadId, WM_QUIT, 0, 0)) {
228 // Note: The combination/perfect-storm of a Global Hook, in a
229 // WinProc that has the EXTENSION_POINT_DISABLE mitigation ON, and the
230 // use of the SendInput or keybd_event API to inject a keystroke,
231 // results in the target becoming unresponsive. If any one of these states
232 // are changed, the problem does not occur.
233 // This means the WM_QUIT message is not handled and the call to
234 // WaitForSingleObject times out. Therefore not checking the return val.
235 ::WaitForSingleObject(event, event_max_wait_ms);
236 EXPECT_TRUE(::CloseHandle(event));
237 } else {
238 // Make sure we don't leave a stray.
239 ::TerminateProcess(proc_info.hProcess, 0);
240 EXPECT_TRUE(false);
241 }
242 EXPECT_TRUE(::CloseHandle(proc_info.hThread));
243 EXPECT_TRUE(::CloseHandle(proc_info.hProcess));
244 }
245
246 //------------------------------------------------------------------------------
247 // 1. Set up our AppInit Dll in registry settings. (Enable)
248 // 2. Spawn our Windows process (with or without mitigation enabled).
249 // 3. Check if our AppInit Dll is loaded in our Windows process or not.
250 // 4. Signal our Windows process to shutdown.
251 // 5. Restore original reg settings.
252 //
253 // Do NOT use any ASSERTs in this function. Cleanup required.
254 //------------------------------------------------------------------------------
255 void TestWin8ExtensionPointAppInitWrapper(bool is_success_test) {
256 PROCESS_INFORMATION proc_info = {};
257 wchar_t* hook_dll = L"sbox_integration_test_hook_dll.dll";
Will Harris 2016/04/04 00:15:08 const
penny 2016/04/11 22:11:58 Done.
258
259 // Get path of current executable.
260 wchar_t path[MAX_PATH];
Will Harris 2016/04/04 00:15:08 not sure exactly what is happening here, you are g
penny 2016/04/11 22:11:59 I actually don't think FilePath helps at all. I'v
Will Harris 2016/04/12 19:39:12 I understand you need to call GetShortPathName as
penny 2016/04/13 22:52:27 Done. I'm not really convinced this is much nicer
261 EXPECT_TRUE(::GetModuleFileNameW(NULL, path, MAX_PATH));
262 // We just want the directory.
263 wchar_t* last_separator = ::wcsrchr(path, L'\\');
264 EXPECT_TRUE(last_separator);
265 last_separator++;
266 *last_separator = L'\0';
267 ::wcsncat(path, hook_dll, (MAX_PATH - ::wcslen(path)));
268 // Prep short-name path to our hook dll, for registry.
269 DWORD length = ::GetShortPathNameW(path, NULL, 0);
270 wchar_t* short_name = new wchar_t[length];
Will Harris 2016/04/04 00:15:08 use a scoped_ptr with a base::FreeDeleter rather t
penny 2016/04/11 22:11:59 Done.
271 EXPECT_TRUE(::GetShortPathNameW(path, short_name, length));
272
273 // 1. Reg setup.
274 wchar_t* app_init_reg_path =
275 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
276 wchar_t* dlls_value_name = L"AppInit_DLLs";
277 wchar_t* enabled_value_name = L"LoadAppInit_DLLs";
278 wchar_t* signing_value_name = L"RequireSignedAppInit_DLLs";
279 std::wstring orig_dlls;
280 std::wstring new_dlls;
281 DWORD orig_enabled_value = 0;
282 DWORD orig_signing_value = 0;
283 base::win::RegKey app_init_key(HKEY_LOCAL_MACHINE, app_init_reg_path,
284 KEY_QUERY_VALUE | KEY_SET_VALUE);
285 // Backup the existing settings.
286 EXPECT_TRUE(app_init_key.Valid());
287 EXPECT_TRUE(app_init_key.HasValue(dlls_value_name) &&
288 app_init_key.HasValue(enabled_value_name));
289 EXPECT_EQ(ERROR_SUCCESS, app_init_key.ReadValue(dlls_value_name, &orig_dlls));
290 EXPECT_EQ(ERROR_SUCCESS,
291 app_init_key.ReadValueDW(enabled_value_name, &orig_enabled_value));
292 if (app_init_key.HasValue(signing_value_name))
293 EXPECT_EQ(ERROR_SUCCESS, app_init_key.ReadValueDW(signing_value_name,
294 &orig_signing_value));
295
296 // Set the new settings we want (obviously requires local admin privileges).
297 new_dlls = orig_dlls;
298 if (0 != orig_dlls.compare(L""))
299 new_dlls.append(L",");
300 new_dlls.append(short_name);
301 delete[] short_name;
302
303 EXPECT_EQ(ERROR_SUCCESS,
304 app_init_key.WriteValue(dlls_value_name, new_dlls.c_str()));
305 if (app_init_key.HasValue(signing_value_name))
306 EXPECT_EQ(ERROR_SUCCESS, app_init_key.WriteValue(signing_value_name,
307 static_cast<DWORD>(0)));
308 EXPECT_EQ(ERROR_SUCCESS,
309 app_init_key.WriteValue(enabled_value_name, static_cast<DWORD>(1)));
Will Harris 2016/04/04 00:15:09 can you just use 1U and avoid the cast here and ab
penny 2016/04/11 22:11:59 So the EXPECT_EQ macro (and the function call) is
310
311 // 2. Spawn WinProc.
312 HANDLE event = ::CreateEventW(NULL, FALSE, FALSE, winproc_event);
Will Harris 2016/04/04 00:15:09 ScopedHandle
penny 2016/04/11 22:11:58 Done.
313 EXPECT_TRUE(event != NULL && event != INVALID_HANDLE_VALUE);
314 SpawnWinProc(&proc_info, is_success_test, &event);
315
316 // 3. Check loaded modules in WinProc to see if AppInit dll is loaded.
317 std::vector<HMODULE>(modules);
318 EXPECT_TRUE(
319 base::win::GetLoadedModulesSnapshot(proc_info.hProcess, &modules));
320 BOOL dll_loaded = FALSE;
321
322 for (auto module : modules) {
323 wchar_t name[MAX_PATH];
324 EXPECT_TRUE(
325 ::GetModuleFileNameExW(proc_info.hProcess, module, name, MAX_PATH));
326
327 // Compare to our dll name!
328 if (::wcsstr(name, hook_dll)) {
329 // Found it.
330 dll_loaded = TRUE;
331 break;
332 }
333 }
334
335 // Did we pass the test as expected?
336 EXPECT_EQ((is_success_test ? TRUE : FALSE), dll_loaded);
337
338 // 4. Trigger shutdown of WinProc.
339 if (::PostThreadMessageW(proc_info.dwThreadId, WM_QUIT, 0, 0)) {
340 ::WaitForSingleObject(event, event_max_wait_ms);
341 EXPECT_TRUE(::CloseHandle(event));
342 } else {
343 // Make sure we don't leave a stray.
344 ::TerminateProcess(proc_info.hProcess, 0);
345 EXPECT_TRUE(false);
346 }
347 EXPECT_TRUE(::CloseHandle(proc_info.hThread));
348 EXPECT_TRUE(::CloseHandle(proc_info.hProcess));
349
350 // 5. Reg Restore
351 EXPECT_EQ(ERROR_SUCCESS,
352 app_init_key.WriteValue(enabled_value_name, orig_enabled_value));
353 if (app_init_key.HasValue(signing_value_name))
354 EXPECT_EQ(ERROR_SUCCESS,
355 app_init_key.WriteValue(signing_value_name, orig_signing_value));
356 EXPECT_EQ(ERROR_SUCCESS,
357 app_init_key.WriteValue(dlls_value_name, orig_dlls.c_str()));
358 app_init_key.Close();
359 }
360
109 void TestWin10ImageLoadRemote(bool is_success_test) { 361 void TestWin10ImageLoadRemote(bool is_success_test) {
110 // ***Insert your manual testing share UNC path here! 362 // ***Insert your manual testing share UNC path here!
111 // E.g.: \\\\hostname\\sharename\\calc.exe 363 // E.g.: \\\\hostname\\sharename\\calc.exe
112 std::wstring unc = L"\"\\\\hostname\\sharename\\calc.exe\""; 364 std::wstring unc = L"\"\\\\hostname\\sharename\\calc.exe\"";
113 365
114 sandbox::TestRunner runner; 366 sandbox::TestRunner runner;
115 sandbox::TargetPolicy* policy = runner.GetPolicy(); 367 sandbox::TargetPolicy* policy = runner.GetPolicy();
116 368
117 // Set a policy that would normally allow for process creation. 369 // Set a policy that would normally allow for process creation.
118 policy->SetJobLevel(sandbox::JOB_NONE, 0); 370 policy->SetJobLevel(sandbox::JOB_NONE, 0);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 setup_proc.Terminate(desired_exit_code, false); 481 setup_proc.Terminate(desired_exit_code, false);
230 return SBOX_TEST_SUCCEEDED; 482 return SBOX_TEST_SUCCEEDED;
231 } 483 }
232 // Note: GetLastError from CreateProcess returns 5, "ERROR_ACCESS_DENIED". 484 // Note: GetLastError from CreateProcess returns 5, "ERROR_ACCESS_DENIED".
233 return SBOX_TEST_FAILED; 485 return SBOX_TEST_FAILED;
234 } 486 }
235 487
236 //------------------------------------------------------------------------------ 488 //------------------------------------------------------------------------------
237 // Win8 Checks: 489 // Win8 Checks:
238 // MITIGATION_DEP(_NO_ATL_THUNK) 490 // MITIGATION_DEP(_NO_ATL_THUNK)
239 // MITIGATION_EXTENSION_DLL_DISABLE
240 // MITIGATION_RELOCATE_IMAGE(_REQUIRED) - ASLR, release only 491 // MITIGATION_RELOCATE_IMAGE(_REQUIRED) - ASLR, release only
241 // MITIGATION_STRICT_HANDLE_CHECKS 492 // MITIGATION_STRICT_HANDLE_CHECKS
242 // >= Win8 493 // >= Win8
243 //------------------------------------------------------------------------------ 494 //------------------------------------------------------------------------------
244 495
245 SBOX_TESTS_COMMAND int CheckWin8(int argc, wchar_t **argv) { 496 SBOX_TESTS_COMMAND int CheckWin8(int argc, wchar_t **argv) {
246 get_process_mitigation_policy = 497 get_process_mitigation_policy =
247 reinterpret_cast<GetProcessMitigationPolicyFunction>( 498 reinterpret_cast<GetProcessMitigationPolicyFunction>(
248 ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), 499 ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"),
249 "GetProcessMitigationPolicy")); 500 "GetProcessMitigationPolicy"));
250 if (!get_process_mitigation_policy) 501 if (!get_process_mitigation_policy)
251 return SBOX_TEST_NOT_FOUND; 502 return SBOX_TEST_NOT_FOUND;
252 503
253 #if !defined(_WIN64) // DEP is always enabled on 64-bit. 504 #if !defined(_WIN64) // DEP is always enabled on 64-bit.
254 if (!CheckWin8DepPolicy()) 505 if (!CheckWin8DepPolicy())
255 return SBOX_TEST_FIRST_ERROR; 506 return SBOX_TEST_FIRST_ERROR;
256 #endif 507 #endif
257 508
258 #if defined(NDEBUG) // ASLR cannot be forced in debug builds. 509 #if defined(NDEBUG) // ASLR cannot be forced in debug builds.
259 if (!CheckWin8AslrPolicy()) 510 if (!CheckWin8AslrPolicy())
260 return SBOX_TEST_SECOND_ERROR; 511 return SBOX_TEST_SECOND_ERROR;
261 #endif 512 #endif
262 513
263 if (!CheckWin8StrictHandlePolicy()) 514 if (!CheckWin8StrictHandlePolicy())
264 return SBOX_TEST_THIRD_ERROR; 515 return SBOX_TEST_THIRD_ERROR;
265 516
266 if (!CheckWin8DllExtensionPolicy())
267 return SBOX_TEST_FIFTH_ERROR;
268
269 return SBOX_TEST_SUCCEEDED; 517 return SBOX_TEST_SUCCEEDED;
270 } 518 }
271 519
272 TEST(ProcessMitigationsTest, CheckWin8) { 520 TEST(ProcessMitigationsTest, CheckWin8) {
273 if (base::win::GetVersion() < base::win::VERSION_WIN8) 521 if (base::win::GetVersion() < base::win::VERSION_WIN8)
274 return; 522 return;
275 523
276 TestRunner runner; 524 TestRunner runner;
277 sandbox::TargetPolicy* policy = runner.GetPolicy(); 525 sandbox::TargetPolicy* policy = runner.GetPolicy();
278 526
279 sandbox::MitigationFlags mitigations = MITIGATION_DEP | 527 sandbox::MitigationFlags mitigations =
280 MITIGATION_DEP_NO_ATL_THUNK | 528 MITIGATION_DEP | MITIGATION_DEP_NO_ATL_THUNK;
281 MITIGATION_EXTENSION_DLL_DISABLE;
282 #if defined(NDEBUG) // ASLR cannot be forced in debug builds. 529 #if defined(NDEBUG) // ASLR cannot be forced in debug builds.
283 mitigations |= MITIGATION_RELOCATE_IMAGE | 530 mitigations |= MITIGATION_RELOCATE_IMAGE |
284 MITIGATION_RELOCATE_IMAGE_REQUIRED; 531 MITIGATION_RELOCATE_IMAGE_REQUIRED;
285 #endif 532 #endif
286 533
287 EXPECT_EQ(policy->SetProcessMitigations(mitigations), SBOX_ALL_OK); 534 EXPECT_EQ(policy->SetProcessMitigations(mitigations), SBOX_ALL_OK);
288 535
289 mitigations |= MITIGATION_STRICT_HANDLE_CHECKS; 536 mitigations |= MITIGATION_STRICT_HANDLE_CHECKS;
290 537
291 EXPECT_EQ(policy->SetDelayedProcessMitigations(mitigations), SBOX_ALL_OK); 538 EXPECT_EQ(policy->SetDelayedProcessMitigations(mitigations), SBOX_ALL_OK);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 653
407 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE), 654 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
408 SBOX_ALL_OK); 655 SBOX_ALL_OK);
409 EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN, 656 EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
410 sandbox::TargetPolicy::FAKE_USER_GDI_INIT, NULL), 657 sandbox::TargetPolicy::FAKE_USER_GDI_INIT, NULL),
411 sandbox::SBOX_ALL_OK); 658 sandbox::SBOX_ALL_OK);
412 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown")); 659 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown"));
413 } 660 }
414 661
415 //------------------------------------------------------------------------------ 662 //------------------------------------------------------------------------------
663 // Disable extension points (MITIGATION_EXTENSION_POINT_DISABLE).
664 // >= Win8
665 //------------------------------------------------------------------------------
666
667 wchar_t* extension_point_mutex = L"ChromeExtensionTestMutex";
668 DWORD mutex_max_wait_ms = 10 * 1000;
Will Harris 2016/04/04 00:15:08 TestTimeouts::action_timeout() for defaults
penny 2016/04/11 22:11:58 So TestTimeouts::action_timeout() returns a base::
669
670 SBOX_TESTS_COMMAND int CheckWin8ExtensionPointSetting(int argc,
671 wchar_t** argv) {
672 get_process_mitigation_policy =
673 reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress(
674 ::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy"));
675 if (!get_process_mitigation_policy)
676 return SBOX_TEST_NOT_FOUND;
677
678 if (!CheckWin8ExtensionPointPolicy())
679 return SBOX_TEST_FIRST_ERROR;
680 return SBOX_TEST_SUCCEEDED;
681 }
682
683 // This test validates that setting the MITIGATION_EXTENSION_POINT_DISABLE
684 // mitigation enables the setting on a process.
685 TEST(ProcessMitigationsTest, CheckWin8ExtensionPointPolicySuccess) {
686 if (base::win::GetVersion() < base::win::VERSION_WIN8)
687 return;
688
689 TestRunner runner;
690 sandbox::TargetPolicy* policy = runner.GetPolicy();
691
692 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_EXTENSION_POINT_DISABLE),
693 SBOX_ALL_OK);
694 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
695 runner.RunTest(L"CheckWin8ExtensionPointSetting"));
696 }
697
698 // This test validates that we CAN add a "legitimate" global hook on the
699 // sandboxed
700 // proc/thread if the MITIGATION_EXTENSION_POINT_DISABLE mitigation is not set.
701 //
702 // MANUAL testing only.
703 TEST(ProcessMitigationsTest,
704 DISABLED_CheckWin8ExtensionPoint_GlobalHook_Success) {
705 if (base::win::GetVersion() < base::win::VERSION_WIN8)
706 return;
707
708 HANDLE mutex = ::CreateMutexW(NULL, FALSE, extension_point_mutex);
709 EXPECT_TRUE(mutex != NULL && mutex != INVALID_HANDLE_VALUE);
710 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(mutex, mutex_max_wait_ms));
711
712 // (is_success_test, global_hook)
713 TestWin8ExtensionPointHookWrapper(true, true);
714
715 EXPECT_TRUE(::ReleaseMutex(mutex));
716 EXPECT_TRUE(::CloseHandle(mutex));
717 }
718
719 // This test validates that setting the MITIGATION_EXTENSION_POINT_DISABLE
720 // mitigation prevents a global hook in our WinProc.
721 //
722 // MANUAL testing only.
723 TEST(ProcessMitigationsTest,
724 DISABLED_CheckWin8ExtensionPoint_GlobalHook_Failure) {
725 if (base::win::GetVersion() < base::win::VERSION_WIN8)
726 return;
727
728 HANDLE mutex = ::CreateMutexW(NULL, FALSE, extension_point_mutex);
729 EXPECT_TRUE(mutex != NULL && mutex != INVALID_HANDLE_VALUE);
730 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(mutex, mutex_max_wait_ms));
731
732 // (is_success_test, global_hook)
733 TestWin8ExtensionPointHookWrapper(false, true);
734
735 EXPECT_TRUE(::ReleaseMutex(mutex));
736 EXPECT_TRUE(::CloseHandle(mutex));
737 }
738
739 // This test validates that we CAN add a "legitimate" hook on the sandboxed
740 // proc/thread if the MITIGATION_EXTENSION_POINT_DISABLE mitigation is not set.
741 //
742 // MANUAL testing only.
743 TEST(ProcessMitigationsTest, DISABLED_CheckWin8ExtensionPoint_Hook_Success) {
744 if (base::win::GetVersion() < base::win::VERSION_WIN8)
745 return;
746
747 HANDLE mutex = ::CreateMutexW(NULL, FALSE, extension_point_mutex);
748 EXPECT_TRUE(mutex != NULL && mutex != INVALID_HANDLE_VALUE);
749 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(mutex, mutex_max_wait_ms));
750
751 // (is_success_test, global_hook)
752 TestWin8ExtensionPointHookWrapper(true, false);
753
754 EXPECT_TRUE(::ReleaseMutex(mutex));
755 EXPECT_TRUE(::CloseHandle(mutex));
756 }
757
758 // *** Important: MITIGATION_EXTENSION_POINT_DISABLE does NOT prevent
759 // hooks targetted at a specific thread id. It only prevents
760 // global hooks. So this test does NOT actually expect the hook
761 // to fail (see TestWin8ExtensionPointHookWrapper function) even
762 // with the mitigation on.
763 //
764 // MANUAL testing only.
765 TEST(ProcessMitigationsTest, DISABLED_CheckWin8ExtensionPoint_Hook_Failure) {
766 if (base::win::GetVersion() < base::win::VERSION_WIN8)
767 return;
768
769 HANDLE mutex = ::CreateMutexW(NULL, FALSE, extension_point_mutex);
770 EXPECT_TRUE(mutex != NULL && mutex != INVALID_HANDLE_VALUE);
771 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(mutex, mutex_max_wait_ms));
772
773 // (is_success_test, global_hook)
774 TestWin8ExtensionPointHookWrapper(false, false);
775
776 EXPECT_TRUE(::ReleaseMutex(mutex));
777 EXPECT_TRUE(::CloseHandle(mutex));
778 }
779
780 // This test validates that we CAN add an AppInit Dll to a target
781 // WinProc if the MITIGATION_EXTENSION_POINT_DISABLE mitigation is not set.
782 //
783 // MANUAL testing only.
784 // Must run this test as admin/elevated.
785 TEST(ProcessMitigationsTest, DISABLED_CheckWin8ExtensionPoint_AppInit_Success) {
786 if (base::win::GetVersion() < base::win::VERSION_WIN8)
787 return;
788
789 HANDLE mutex = ::CreateMutexW(NULL, FALSE, extension_point_mutex);
790 EXPECT_TRUE(mutex != NULL && mutex != INVALID_HANDLE_VALUE);
791 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(mutex, mutex_max_wait_ms));
792
793 TestWin8ExtensionPointAppInitWrapper(true);
794
795 EXPECT_TRUE(::ReleaseMutex(mutex));
796 EXPECT_TRUE(::CloseHandle(mutex));
797 }
798
799 // This test validates that setting the MITIGATION_EXTENSION_POINT_DISABLE
800 // mitigation prevents the loading of any AppInit Dll into our WinProc.
801 //
802 // MANUAL testing only.
803 // Must run this test as admin/elevated.
804 TEST(ProcessMitigationsTest, DISABLED_CheckWin8ExtensionPoint_AppInit_Failure) {
805 if (base::win::GetVersion() < base::win::VERSION_WIN8)
806 return;
807
808 HANDLE mutex = ::CreateMutexW(NULL, FALSE, extension_point_mutex);
809 EXPECT_TRUE(mutex != NULL && mutex != INVALID_HANDLE_VALUE);
810 EXPECT_EQ(WAIT_OBJECT_0, ::WaitForSingleObject(mutex, mutex_max_wait_ms));
811
812 TestWin8ExtensionPointAppInitWrapper(false);
813
814 EXPECT_TRUE(::ReleaseMutex(mutex));
815 EXPECT_TRUE(::CloseHandle(mutex));
816 }
817
818 //------------------------------------------------------------------------------
416 // Disable non-system font loads (MITIGATION_NONSYSTEM_FONT_DISABLE) 819 // Disable non-system font loads (MITIGATION_NONSYSTEM_FONT_DISABLE)
417 // >= Win10 820 // >= Win10
418 //------------------------------------------------------------------------------ 821 //------------------------------------------------------------------------------
419 822
420 SBOX_TESTS_COMMAND int CheckWin10FontLockDown(int argc, wchar_t** argv) { 823 SBOX_TESTS_COMMAND int CheckWin10FontLockDown(int argc, wchar_t** argv) {
421 get_process_mitigation_policy = 824 get_process_mitigation_policy =
422 reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress( 825 reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress(
423 ::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy")); 826 ::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy"));
424 if (!get_process_mitigation_policy) 827 if (!get_process_mitigation_policy)
425 return SBOX_TEST_NOT_FOUND; 828 return SBOX_TEST_NOT_FOUND;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 policy->SetDelayedProcessMitigations(MITIGATION_IMAGE_LOAD_NO_REMOTE), 973 policy->SetDelayedProcessMitigations(MITIGATION_IMAGE_LOAD_NO_REMOTE),
571 SBOX_ALL_OK); 974 SBOX_ALL_OK);
572 EXPECT_EQ(SBOX_TEST_SUCCEEDED, 975 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
573 runner.RunTest(L"CheckWin10ImageLoadNoRemote")); 976 runner.RunTest(L"CheckWin10ImageLoadNoRemote"));
574 } 977 }
575 978
576 // This test validates that we CAN create a new process from 979 // This test validates that we CAN create a new process from
577 // a remote UNC device, if the MITIGATION_IMAGE_LOAD_NO_REMOTE 980 // a remote UNC device, if the MITIGATION_IMAGE_LOAD_NO_REMOTE
578 // mitigation is NOT set. 981 // mitigation is NOT set.
579 // 982 //
580 // DISABLED for automated testing bots. Enable for manual testing. 983 // MANUAL testing only.
581 TEST(ProcessMitigationsTest, DISABLED_CheckWin10ImageLoadNoRemoteSuccess) { 984 TEST(ProcessMitigationsTest, DISABLED_CheckWin10ImageLoadNoRemoteSuccess) {
582 if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2) 985 if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2)
583 return; 986 return;
584 987
585 TestWin10ImageLoadRemote(true); 988 TestWin10ImageLoadRemote(true);
586 } 989 }
587 990
588 // This test validates that setting the MITIGATION_IMAGE_LOAD_NO_REMOTE 991 // This test validates that setting the MITIGATION_IMAGE_LOAD_NO_REMOTE
589 // mitigation prevents creating a new process from a remote 992 // mitigation prevents creating a new process from a remote
590 // UNC device. 993 // UNC device.
591 // 994 //
592 // DISABLED for automated testing bots. Enable for manual testing. 995 // MANUAL testing only.
593 TEST(ProcessMitigationsTest, DISABLED_CheckWin10ImageLoadNoRemoteFailure) { 996 TEST(ProcessMitigationsTest, DISABLED_CheckWin10ImageLoadNoRemoteFailure) {
594 if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2) 997 if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2)
595 return; 998 return;
596 999
597 TestWin10ImageLoadRemote(false); 1000 TestWin10ImageLoadRemote(false);
598 } 1001 }
599 1002
600 //------------------------------------------------------------------------------ 1003 //------------------------------------------------------------------------------
601 // Disable image load when "mandatory low label" (integrity level). 1004 // Disable image load when "mandatory low label" (integrity level).
602 // (MITIGATION_IMAGE_LOAD_NO_LOW_LABEL) 1005 // (MITIGATION_IMAGE_LOAD_NO_LOW_LABEL)
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 cmd = cmd.Append(L"calc.exe"); 1152 cmd = cmd.Append(L"calc.exe");
750 1153
751 std::wstring test_command = L"TestChildProcess "; 1154 std::wstring test_command = L"TestChildProcess ";
752 test_command += cmd.value().c_str(); 1155 test_command += cmd.value().c_str();
753 test_command += L" 1"; 1156 test_command += L" 1";
754 1157
755 EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(test_command.c_str())); 1158 EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(test_command.c_str()));
756 } 1159 }
757 1160
758 } // namespace sandbox 1161 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698