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

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

Powered by Google App Engine
This is Rietveld 408576698