OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 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 "sandbox/win/src/process_mitigations.h" | |
6 | |
7 #include <windows.h> | |
8 | |
9 #include "base/files/file_util.h" | |
10 #include "base/path_service.h" | |
11 #include "base/scoped_native_library.h" | |
12 #include "base/test/test_timeouts.h" | |
13 #include "base/win/windows_version.h" | |
14 #include "sandbox/win/src/nt_internals.h" | |
15 #include "sandbox/win/src/target_services.h" | |
16 #include "sandbox/win/tests/common/controller.h" | |
17 #include "sandbox/win/tests/integration_tests/integration_tests_common.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 | |
20 namespace { | |
21 | |
22 //------------------------------------------------------------------------------ | |
23 // Internal Defines & Functions | |
24 //------------------------------------------------------------------------------ | |
25 | |
26 // API defined in winbase.h. | |
27 using GetProcessDEPPolicyFunction = decltype(&GetProcessDEPPolicy); | |
28 | |
29 // API defined in processthreadsapi.h. | |
30 using GetProcessMitigationPolicyFunction = | |
31 decltype(&GetProcessMitigationPolicy); | |
32 GetProcessMitigationPolicyFunction get_process_mitigation_policy; | |
33 | |
34 // APIs defined in wingdi.h. | |
35 using AddFontMemResourceExFunction = decltype(&AddFontMemResourceEx); | |
36 using RemoveFontMemResourceExFunction = decltype(&RemoveFontMemResourceEx); | |
37 | |
38 //------------------------------------------------------------------------------ | |
39 // NonSystemFont test helper function. | |
40 // | |
41 // 1. Pick font file and set up sandbox to allow read access to it. | |
42 // 2. Trigger test child process (with or without mitigation enabled). | |
43 //------------------------------------------------------------------------------ | |
44 void TestWin10NonSystemFont(bool is_success_test) { | |
45 base::FilePath font_path; | |
46 EXPECT_TRUE(base::PathService::Get(base::DIR_WINDOWS_FONTS, &font_path)); | |
47 // Arial font should always be available | |
48 font_path = font_path.Append(L"arial.ttf"); | |
49 | |
50 sandbox::TestRunner runner; | |
51 EXPECT_TRUE(runner.AddFsRule(sandbox::TargetPolicy::FILES_ALLOW_READONLY, | |
52 font_path.value().c_str())); | |
53 | |
54 if (!is_success_test) { | |
55 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
56 // Turn on the non-system font disable mitigation. | |
57 EXPECT_EQ(policy->SetProcessMitigations( | |
58 sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE), | |
59 sandbox::SBOX_ALL_OK); | |
60 } | |
61 | |
62 std::wstring test_command = L"CheckWin10FontLoad \""; | |
63 test_command += font_path.value().c_str(); | |
64 test_command += L"\""; | |
65 | |
66 EXPECT_EQ((is_success_test ? sandbox::SBOX_TEST_SUCCEEDED | |
67 : sandbox::SBOX_TEST_FAILED), | |
68 runner.RunTest(test_command.c_str())); | |
69 } | |
70 | |
71 } // namespace | |
72 | |
73 namespace sandbox { | |
74 | |
75 // Common function used for timeout with Win APIs like ::WaitForSingleObject(). | |
76 DWORD SboxTestEventTimeout() { | |
77 if (::IsDebuggerPresent()) | |
78 return INFINITE; | |
79 | |
80 return static_cast<DWORD>( | |
81 (TestTimeouts::action_timeout()).InMillisecondsRoundedUp()); | |
82 } | |
83 | |
84 //------------------------------------------------------------------------------ | |
85 // Exported functions called by child test processes. | |
86 //------------------------------------------------------------------------------ | |
87 | |
88 //------------------------------------------------------------------------------ | |
89 // Common test function for checking that a policy was enabled. | |
90 // - Use enum TestPolicy defined in integration_tests_common.h to specify which | |
91 // policy to check - passed as arg1. | |
92 //------------------------------------------------------------------------------ | |
93 SBOX_TESTS_COMMAND int CheckPolicy(int argc, wchar_t** argv) { | |
94 if (argc < 1) | |
95 return SBOX_TEST_INVALID_PARAMETER; | |
96 int test = ::_wtoi(argv[0]); | |
97 if (!test) | |
98 return SBOX_TEST_INVALID_PARAMETER; | |
99 | |
100 get_process_mitigation_policy = | |
101 reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress( | |
102 ::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy")); | |
103 if (!get_process_mitigation_policy) | |
104 return SBOX_TEST_NOT_FOUND; | |
105 | |
106 switch (test) { | |
107 //-------------------------------------------------- | |
108 // MITIGATION_DEP | |
109 // MITIGATION_DEP_NO_ATL_THUNK | |
110 //-------------------------------------------------- | |
111 case (TESTPOLICY_DEP): { | |
112 #if !defined(_WIN64) | |
113 // DEP - always enabled on 64-bit. | |
114 PROCESS_MITIGATION_DEP_POLICY policy = {}; | |
115 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
116 ProcessDEPPolicy, &policy, | |
117 sizeof(policy))) { | |
118 return SBOX_TEST_NOT_FOUND; | |
119 } | |
120 if (!policy.Enable || !policy.Permanent) | |
121 return SBOX_TEST_FAILED; | |
122 #endif // !defined(_WIN64) | |
123 break; | |
124 } | |
125 //-------------------------------------------------- | |
126 // MITIGATION_RELOCATE_IMAGE | |
127 // MITIGATION_RELOCATE_IMAGE_REQUIRED | |
128 //-------------------------------------------------- | |
129 case (TESTPOLICY_ASLR): { | |
130 PROCESS_MITIGATION_ASLR_POLICY policy2 = {}; | |
131 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
132 ProcessASLRPolicy, &policy2, | |
133 sizeof(policy2))) { | |
134 return SBOX_TEST_NOT_FOUND; | |
135 } | |
136 if (!policy2.EnableForceRelocateImages || !policy2.DisallowStrippedImages) | |
137 return SBOX_TEST_FAILED; | |
138 | |
139 break; | |
140 } | |
141 //-------------------------------------------------- | |
142 // MITIGATION_STRICT_HANDLE_CHECKS | |
143 //-------------------------------------------------- | |
144 case (TESTPOLICY_STRICTHANDLE): { | |
145 PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy3 = {}; | |
146 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
147 ProcessStrictHandleCheckPolicy, | |
148 &policy3, sizeof(policy3))) { | |
149 return SBOX_TEST_NOT_FOUND; | |
150 } | |
151 if (!policy3.RaiseExceptionOnInvalidHandleReference || | |
152 !policy3.HandleExceptionsPermanentlyEnabled) { | |
153 return SBOX_TEST_FAILED; | |
154 } | |
155 | |
156 break; | |
157 } | |
158 //-------------------------------------------------- | |
159 // MITIGATION_WIN32K_DISABLE | |
160 //-------------------------------------------------- | |
161 case (TESTPOLICY_WIN32K): { | |
162 PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {}; | |
163 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
164 ProcessSystemCallDisablePolicy, | |
165 &policy, sizeof(policy))) { | |
166 return SBOX_TEST_NOT_FOUND; | |
167 } | |
168 if (!policy.DisallowWin32kSystemCalls) | |
169 return SBOX_TEST_FAILED; | |
170 | |
171 break; | |
172 } | |
173 //-------------------------------------------------- | |
174 // MITIGATION_EXTENSION_POINT_DISABLE | |
175 //-------------------------------------------------- | |
176 case (TESTPOLICY_EXTENSIONPOINT): { | |
177 PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy = {}; | |
178 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
179 ProcessExtensionPointDisablePolicy, | |
180 &policy, sizeof(policy))) { | |
181 return SBOX_TEST_NOT_FOUND; | |
182 } | |
183 if (!policy.DisableExtensionPoints) | |
184 return SBOX_TEST_FAILED; | |
185 | |
186 break; | |
187 } | |
188 //-------------------------------------------------- | |
189 // MITIGATION_NONSYSTEM_FONT_DISABLE | |
190 //-------------------------------------------------- | |
191 case (TESTPOLICY_NONSYSFONT): { | |
192 PROCESS_MITIGATION_FONT_DISABLE_POLICY policy = {}; | |
193 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
194 ProcessFontDisablePolicy, &policy, | |
195 sizeof(policy))) { | |
196 return SBOX_TEST_NOT_FOUND; | |
197 } | |
198 if (!policy.DisableNonSystemFonts) | |
199 return SBOX_TEST_FAILED; | |
200 | |
201 break; | |
202 } | |
203 //-------------------------------------------------- | |
204 // MITIGATION_IMAGE_LOAD_NO_REMOTE | |
205 //-------------------------------------------------- | |
206 case (TESTPOLICY_LOADNOREMOTE): { | |
207 PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {}; | |
208 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
209 ProcessImageLoadPolicy, &policy, | |
210 sizeof(policy))) { | |
211 return SBOX_TEST_NOT_FOUND; | |
212 } | |
213 if (!policy.NoRemoteImages) | |
214 return SBOX_TEST_FAILED; | |
215 | |
216 break; | |
217 } | |
218 //-------------------------------------------------- | |
219 // MITIGATION_IMAGE_LOAD_NO_LOW_LABEL | |
220 //-------------------------------------------------- | |
221 case (TESTPOLICY_LOADNOLOW): { | |
222 PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {}; | |
223 if (!get_process_mitigation_policy(::GetCurrentProcess(), | |
224 ProcessImageLoadPolicy, &policy, | |
225 sizeof(policy))) { | |
226 return SBOX_TEST_NOT_FOUND; | |
227 } | |
228 if (!policy.NoLowMandatoryLabelImages) | |
229 return SBOX_TEST_FAILED; | |
230 | |
231 break; | |
232 } | |
233 default: | |
234 return SBOX_TEST_INVALID_PARAMETER; | |
235 } | |
236 | |
237 return SBOX_TEST_SUCCEEDED; | |
238 } | |
239 | |
240 SBOX_TESTS_COMMAND int CheckDep(int argc, wchar_t** argv) { | |
241 GetProcessDEPPolicyFunction get_process_dep_policy = | |
242 reinterpret_cast<GetProcessDEPPolicyFunction>(::GetProcAddress( | |
243 ::GetModuleHandleW(L"kernel32.dll"), "GetProcessDEPPolicy")); | |
244 if (get_process_dep_policy) { | |
245 BOOL is_permanent = FALSE; | |
246 DWORD dep_flags = 0; | |
247 | |
248 if (!get_process_dep_policy(::GetCurrentProcess(), &dep_flags, | |
249 &is_permanent)) { | |
250 return SBOX_TEST_FIRST_ERROR; | |
251 } | |
252 | |
253 if (!(dep_flags & PROCESS_DEP_ENABLE) || !is_permanent) | |
254 return SBOX_TEST_SECOND_ERROR; | |
255 | |
256 } else { | |
257 NtQueryInformationProcessFunction query_information_process = NULL; | |
258 ResolveNTFunctionPtr("NtQueryInformationProcess", | |
259 &query_information_process); | |
260 if (!query_information_process) | |
261 return SBOX_TEST_NOT_FOUND; | |
262 | |
263 ULONG size = 0; | |
264 ULONG dep_flags = 0; | |
265 if (!SUCCEEDED(query_information_process(::GetCurrentProcess(), | |
266 ProcessExecuteFlags, &dep_flags, | |
267 sizeof(dep_flags), &size))) { | |
268 return SBOX_TEST_THIRD_ERROR; | |
269 } | |
270 | |
271 static const int MEM_EXECUTE_OPTION_DISABLE = 2; | |
272 static const int MEM_EXECUTE_OPTION_PERMANENT = 8; | |
273 dep_flags &= 0xff; | |
274 | |
275 if (dep_flags != | |
276 (MEM_EXECUTE_OPTION_DISABLE | MEM_EXECUTE_OPTION_PERMANENT)) { | |
277 return SBOX_TEST_FOURTH_ERROR; | |
278 } | |
279 } | |
280 | |
281 return SBOX_TEST_SUCCEEDED; | |
282 } | |
283 | |
284 // ForceMsSigned tests: | |
285 // Try to load the DLL given in arg1. | |
286 SBOX_TESTS_COMMAND int TestDllLoad(int argc, wchar_t** argv) { | |
287 if (argc < 1 || argv[0] == nullptr) | |
288 return SBOX_TEST_INVALID_PARAMETER; | |
289 | |
290 std::wstring dll = argv[0]; | |
291 base::ScopedNativeLibrary test_dll((base::FilePath(dll))); | |
292 if (test_dll.is_valid()) | |
293 return SBOX_TEST_SUCCEEDED; | |
294 | |
295 // Note: GetLastError() does not get an accurate failure code | |
296 // at this point. | |
297 return SBOX_TEST_FAILED; | |
298 } | |
299 | |
300 // This test attempts a non-system font load. | |
301 // | |
302 // 1) Load gdi32.dll for required font APIs. | |
303 // 2) Load file contents of font file passed in arg1 into memory. | |
304 // 3) Call API to try loading a non-system font. | |
305 // | |
306 // Arg1: Full path to font file to try loading. | |
307 SBOX_TESTS_COMMAND int CheckWin10FontLoad(int argc, wchar_t** argv) { | |
308 if (argc < 1) | |
309 return SBOX_TEST_INVALID_PARAMETER; | |
310 | |
311 HMODULE gdi_module = ::LoadLibraryW(L"gdi32.dll"); | |
312 if (!gdi_module) | |
313 return SBOX_TEST_NOT_FOUND; | |
314 | |
315 AddFontMemResourceExFunction add_font_mem_resource = | |
316 reinterpret_cast<AddFontMemResourceExFunction>( | |
317 ::GetProcAddress(gdi_module, "AddFontMemResourceEx")); | |
318 | |
319 RemoveFontMemResourceExFunction rem_font_mem_resource = | |
320 reinterpret_cast<RemoveFontMemResourceExFunction>( | |
321 ::GetProcAddress(gdi_module, "RemoveFontMemResourceEx")); | |
322 | |
323 if (!add_font_mem_resource || !rem_font_mem_resource) | |
324 return SBOX_TEST_NOT_FOUND; | |
325 | |
326 // Open font file passed in as an argument. | |
327 base::File file(base::FilePath(argv[0]), | |
328 base::File::FLAG_OPEN | base::File::FLAG_READ); | |
329 if (!file.IsValid()) | |
330 // Failed to open the font file passed in. | |
331 return SBOX_TEST_NOT_FOUND; | |
332 | |
333 std::vector<char> font_data; | |
334 int64_t len = file.GetLength(); | |
335 if (len < 0) | |
336 return SBOX_TEST_NOT_FOUND; | |
337 font_data.resize(len); | |
338 | |
339 int read = file.Read(0, &font_data[0], len); | |
340 file.Close(); | |
341 | |
342 if (read != len) | |
343 return SBOX_TEST_NOT_FOUND; | |
344 | |
345 DWORD font_count = 0; | |
346 HANDLE font_handle = add_font_mem_resource( | |
347 &font_data[0], static_cast<DWORD>(font_data.size()), NULL, &font_count); | |
348 | |
349 if (font_handle) { | |
350 rem_font_mem_resource(font_handle); | |
351 return SBOX_TEST_SUCCEEDED; | |
352 } | |
353 | |
354 return SBOX_TEST_FAILED; | |
355 } | |
356 | |
357 // Common helper test for CreateProcess. | |
358 // Arg1: The process commandline to create. | |
359 // Arg2: Will process end on its own: | |
360 // - "true" for a process expected to finish on its own (wait for it). | |
361 // - "false" for a process that will require terminating. | |
362 // Arg3: [OPTIONAL] Expected or forced exit code: | |
363 // - If arg2 is "true", this is the expected exit code (default 0). | |
364 // - If arg2 is "false", terminate the process with this exit code (default 0). | |
365 // | |
366 // ***Make sure you've enabled basic process creation in the | |
367 // test sandbox settings via: | |
368 // sandbox::TargetPolicy::SetJobLevel(), | |
369 // sandbox::TargetPolicy::SetTokenLevel(), | |
370 // and TestRunner::SetDisableCsrss(). | |
371 SBOX_TESTS_COMMAND int TestChildProcess(int argc, wchar_t** argv) { | |
372 if (argc < 2 || argc > 3) | |
373 return SBOX_TEST_INVALID_PARAMETER; | |
374 | |
375 bool process_finishes = true; | |
376 std::wstring arg2 = argv[1]; | |
377 if (arg2.compare(L"false") == 0) | |
378 process_finishes = false; | |
379 | |
380 int desired_exit_code = 0; | |
381 if (argc == 3) { | |
382 desired_exit_code = wcstoul(argv[2], nullptr, 0); | |
383 } | |
384 | |
385 std::wstring cmd = argv[0]; | |
386 base::LaunchOptions options = base::LaunchOptionsForTest(); | |
387 base::Process setup_proc = base::LaunchProcess(cmd.c_str(), options); | |
388 | |
389 if (setup_proc.IsValid()) { | |
390 if (process_finishes) { | |
391 // Wait for process exit and compare exit code. | |
392 int exit_code = 1; | |
393 if (!setup_proc.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), | |
394 &exit_code)) { | |
395 // Unexpected failure. | |
396 setup_proc.Terminate(0, false); | |
397 return SBOX_TEST_TIMED_OUT; | |
398 } | |
399 if (exit_code != desired_exit_code) | |
400 return SBOX_TEST_FAILED; | |
401 return SBOX_TEST_SUCCEEDED; | |
402 } else { | |
403 // Terminate process with requested exit code. | |
404 setup_proc.Terminate(desired_exit_code, false); | |
405 return SBOX_TEST_SUCCEEDED; | |
406 } | |
407 } | |
408 // Process failed to be created. | |
409 // Note: GetLastError from CreateProcess returns 5, "ERROR_ACCESS_DENIED". | |
410 return SBOX_TEST_FAILED; | |
411 } | |
412 | |
413 //------------------------------------------------------------------------------ | |
414 // Exported Mitigation Tests | |
415 //------------------------------------------------------------------------------ | |
416 | |
417 //------------------------------------------------------------------------------ | |
418 // DEP (MITIGATION_DEP and MITIGATION_DEP_NO_ATL_THUNK) | |
419 // Win7 x86 | |
420 //------------------------------------------------------------------------------ | |
421 | |
422 #if !defined(_WIN64) | |
423 // DEP is always enabled on 64-bit. Only test on x86. | |
424 TEST(ProcessMitigationsTest, CheckDepWin7) { | |
425 if (base::win::GetVersion() > base::win::VERSION_WIN7) | |
426 return; | |
427 | |
428 TestRunner runner; | |
429 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
430 | |
431 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_DEP | | |
432 MITIGATION_DEP_NO_ATL_THUNK | | |
433 MITIGATION_SEHOP), | |
434 SBOX_ALL_OK); | |
435 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDep")); | |
436 } | |
437 #endif // !defined(_WIN64) | |
438 | |
439 //------------------------------------------------------------------------------ | |
440 // DEP (MITIGATION_DEP and MITIGATION_DEP_NO_ATL_THUNK) | |
441 // >= Win8 x86 | |
442 //------------------------------------------------------------------------------ | |
443 | |
444 #if !defined(_WIN64) | |
445 // DEP is always enabled on 64-bit. Only test on x86. | |
446 | |
447 // This test validates that setting the MITIGATION_DEP* | |
448 // mitigations enables the setting on a process. | |
449 TEST(ProcessMitigationsTest, CheckDepWin8PolicySuccess) { | |
450 if (base::win::GetVersion() < base::win::VERSION_WIN8) | |
451 return; | |
452 | |
453 std::wstring test_command = L"CheckPolicy "; | |
Will Harris
2017/06/28 12:27:54
style guide says do not use std::wstring except fo
penny
2017/06/28 22:33:33
Done. In each file I touched. Thanks!
| |
454 test_command += std::to_wstring(TESTPOLICY_DEP); | |
455 | |
456 //--------------------------------- | |
457 // 1) Test setting pre-startup. | |
458 //--------------------------------- | |
459 TestRunner runner; | |
460 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
461 | |
462 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_DEP | | |
463 MITIGATION_DEP_NO_ATL_THUNK), | |
464 SBOX_ALL_OK); | |
465 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); | |
466 | |
467 //--------------------------------- | |
468 // 2) Test setting post-startup. | |
469 //--------------------------------- | |
470 TestRunner runner2; | |
471 sandbox::TargetPolicy* policy2 = runner2.GetPolicy(); | |
472 | |
473 EXPECT_EQ(policy2->SetDelayedProcessMitigations(MITIGATION_DEP | | |
474 MITIGATION_DEP_NO_ATL_THUNK), | |
475 SBOX_ALL_OK); | |
476 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str())); | |
477 } | |
478 | |
479 #endif // !defined(_WIN64) | |
480 | |
481 //------------------------------------------------------------------------------ | |
482 // ASLR | |
483 // - MITIGATION_RELOCATE_IMAGE | |
484 // - MITIGATION_RELOCATE_IMAGE_REQUIRED | |
485 // - MITIGATION_BOTTOM_UP_ASLR | |
486 // - MITIGATION_HIGH_ENTROPY_ASLR | |
487 // >= Win8 | |
488 //------------------------------------------------------------------------------ | |
489 | |
490 TEST(ProcessMitigationsTest, CheckWin8AslrPolicySuccess) { | |
491 if (base::win::GetVersion() < base::win::VERSION_WIN8) | |
492 return; | |
493 | |
494 std::wstring test_command = L"CheckPolicy "; | |
495 test_command += std::to_wstring(TESTPOLICY_ASLR); | |
496 | |
497 TestRunner runner; | |
498 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
499 | |
500 //--------------------------------- | |
501 // 1) Test setting pre-startup. | |
502 // **Can only set ASLR pre-startup in release build. | |
503 //--------------------------------- | |
504 #if defined(NDEBUG) | |
505 EXPECT_EQ(policy->SetProcessMitigations( | |
506 MITIGATION_RELOCATE_IMAGE | MITIGATION_RELOCATE_IMAGE_REQUIRED | | |
507 MITIGATION_BOTTOM_UP_ASLR | MITIGATION_HIGH_ENTROPY_ASLR), | |
508 SBOX_ALL_OK); | |
509 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); | |
510 | |
511 //--------------------------------- | |
512 // 2) Test setting post-startup. | |
513 // **Bottom up and high entropy can only be set pre-startup. | |
514 // **Can only set ASLR post-startup in debug build. | |
515 //--------------------------------- | |
516 #else | |
517 EXPECT_EQ(policy->SetDelayedProcessMitigations( | |
518 MITIGATION_RELOCATE_IMAGE | MITIGATION_RELOCATE_IMAGE_REQUIRED), | |
519 SBOX_ALL_OK); | |
520 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); | |
521 #endif // !defined(NDEBUG) | |
522 } | |
523 | |
524 //------------------------------------------------------------------------------ | |
525 // Strict handle checks (MITIGATION_STRICT_HANDLE_CHECKS) | |
526 // >= Win8 | |
527 //------------------------------------------------------------------------------ | |
528 | |
529 TEST(ProcessMitigationsTest, CheckWin8StrictHandlePolicySuccess) { | |
530 if (base::win::GetVersion() < base::win::VERSION_WIN8) | |
531 return; | |
532 | |
533 std::wstring test_command = L"CheckPolicy "; | |
534 test_command += std::to_wstring(TESTPOLICY_STRICTHANDLE); | |
535 | |
536 //--------------------------------- | |
537 // 1) Test setting post-startup. | |
538 // ** Can only be set post-startup. | |
539 //--------------------------------- | |
540 TestRunner runner; | |
541 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
542 | |
543 EXPECT_EQ( | |
544 policy->SetDelayedProcessMitigations(MITIGATION_STRICT_HANDLE_CHECKS), | |
545 SBOX_ALL_OK); | |
546 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); | |
547 } | |
548 | |
549 //------------------------------------------------------------------------------ | |
550 // Disable non-system font loads (MITIGATION_NONSYSTEM_FONT_DISABLE) | |
551 // >= Win10 | |
552 //------------------------------------------------------------------------------ | |
553 | |
554 // This test validates that setting the MITIGATION_NON_SYSTEM_FONTS_DISABLE | |
555 // mitigation enables the setting on a process. | |
556 TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownPolicySuccess) { | |
557 if (base::win::GetVersion() < base::win::VERSION_WIN10) | |
558 return; | |
559 | |
560 std::wstring test_command = L"CheckPolicy "; | |
561 test_command += std::to_wstring(TESTPOLICY_NONSYSFONT); | |
562 | |
563 //--------------------------------- | |
564 // 1) Test setting pre-startup. | |
565 //--------------------------------- | |
566 TestRunner runner; | |
567 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
568 | |
569 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_NONSYSTEM_FONT_DISABLE), | |
570 SBOX_ALL_OK); | |
571 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); | |
572 | |
573 //--------------------------------- | |
574 // 2) Test setting post-startup. | |
575 //--------------------------------- | |
576 TestRunner runner2; | |
577 sandbox::TargetPolicy* policy2 = runner2.GetPolicy(); | |
578 | |
579 EXPECT_EQ( | |
580 policy2->SetDelayedProcessMitigations(MITIGATION_NONSYSTEM_FONT_DISABLE), | |
581 SBOX_ALL_OK); | |
582 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str())); | |
583 } | |
584 | |
585 // This test validates that we can load a non-system font if the | |
586 // MITIGATION_NON_SYSTEM_FONTS_DISABLE mitigation is NOT set. | |
587 TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownLoadSuccess) { | |
588 if (base::win::GetVersion() < base::win::VERSION_WIN10) | |
589 return; | |
590 | |
591 TestWin10NonSystemFont(true); | |
592 } | |
593 | |
594 // This test validates that setting the MITIGATION_NON_SYSTEM_FONTS_DISABLE | |
595 // mitigation prevents the loading of a non-system font. | |
596 TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownLoadFailure) { | |
597 if (base::win::GetVersion() < base::win::VERSION_WIN10) | |
598 return; | |
599 | |
600 TestWin10NonSystemFont(false); | |
601 } | |
602 | |
603 //------------------------------------------------------------------------------ | |
604 // Disable child process creation. | |
605 // - JobLevel <= JOB_LIMITED_USER (on < WIN10_TH2). | |
606 // - JobLevel <= JOB_LIMITED_USER which also triggers setting | |
607 // PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY to | |
608 // PROCESS_CREATION_CHILD_PROCESS_RESTRICTED in | |
609 // BrokerServicesBase::SpawnTarget (on >= WIN10_TH2). | |
610 //------------------------------------------------------------------------------ | |
611 | |
612 // This test validates that we can spawn a child process if | |
613 // MITIGATION_CHILD_PROCESS_CREATION_RESTRICTED mitigation is | |
614 // not set. | |
615 TEST(ProcessMitigationsTest, CheckChildProcessSuccess) { | |
616 TestRunner runner; | |
617 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
618 | |
619 // Set a policy that would normally allow for process creation. | |
620 policy->SetJobLevel(JOB_INTERACTIVE, 0); | |
621 policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED); | |
622 runner.SetDisableCsrss(false); | |
623 | |
624 base::FilePath cmd; | |
625 EXPECT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &cmd)); | |
626 cmd = cmd.Append(L"calc.exe"); | |
627 | |
628 std::wstring test_command = L"TestChildProcess \""; | |
629 test_command += cmd.value().c_str(); | |
630 test_command += L"\" false"; | |
631 | |
632 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); | |
633 } | |
634 | |
635 // This test validates that setting the | |
636 // MITIGATION_CHILD_PROCESS_CREATION_RESTRICTED mitigation prevents | |
637 // the spawning of child processes. | |
638 TEST(ProcessMitigationsTest, CheckChildProcessFailure) { | |
639 TestRunner runner; | |
640 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
641 | |
642 // Now set the job level to be <= JOB_LIMITED_USER | |
643 // and ensure we can no longer create a child process. | |
644 policy->SetJobLevel(JOB_LIMITED_USER, 0); | |
645 policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED); | |
646 runner.SetDisableCsrss(false); | |
647 | |
648 base::FilePath cmd; | |
649 EXPECT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &cmd)); | |
650 cmd = cmd.Append(L"calc.exe"); | |
651 | |
652 std::wstring test_command = L"TestChildProcess \""; | |
653 test_command += cmd.value().c_str(); | |
654 test_command += L"\" false"; | |
655 | |
656 EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(test_command.c_str())); | |
657 } | |
658 | |
659 // This test validates that when the sandboxed target within a job spawns a | |
660 // child process and the target process exits abnormally, the broker correctly | |
661 // handles the JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS message. | |
662 // Because this involves spawning a child process from the target process and is | |
663 // very similar to the above CheckChildProcess* tests, this test is here rather | |
664 // than elsewhere closer to the other Job tests. | |
665 TEST(ProcessMitigationsTest, CheckChildProcessAbnormalExit) { | |
666 TestRunner runner; | |
667 sandbox::TargetPolicy* policy = runner.GetPolicy(); | |
668 | |
669 // Set a policy that would normally allow for process creation. | |
670 policy->SetJobLevel(JOB_INTERACTIVE, 0); | |
671 policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED); | |
672 runner.SetDisableCsrss(false); | |
673 | |
674 base::FilePath cmd; | |
675 EXPECT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &cmd)); | |
676 cmd = cmd.Append(L"calc.exe"); | |
677 | |
678 std::wstring test_command = L"TestChildProcess \""; | |
679 test_command += cmd.value().c_str(); | |
680 test_command += L"\" false "; | |
681 test_command += std::to_wstring(STATUS_ACCESS_VIOLATION); | |
682 | |
683 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); | |
684 } | |
685 | |
686 } // namespace sandbox | |
OLD | NEW |