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

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

Issue 1851213002: Remove sandbox on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix nacl compile issues 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
(Empty)
1 // Copyright (c) 2012 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 <memory>
6 #include <string>
7
8 #include "base/memory/free_deleter.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "base/win/scoped_handle.h"
13 #include "base/win/scoped_process_information.h"
14 #include "base/win/windows_version.h"
15 #include "sandbox/win/src/process_thread_interception.h"
16 #include "sandbox/win/src/sandbox.h"
17 #include "sandbox/win/src/sandbox_factory.h"
18 #include "sandbox/win/src/sandbox_policy.h"
19 #include "sandbox/win/tests/common/controller.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace {
23
24 // Creates a process with the |exe| and |command| parameter using the
25 // unicode and ascii version of the api.
26 sandbox::SboxTestResult CreateProcessHelper(const base::string16& exe,
27 const base::string16& command) {
28 base::win::ScopedProcessInformation pi;
29 STARTUPINFOW si = {sizeof(si)};
30 const wchar_t* exe_name = NULL;
31 if (!exe.empty())
32 exe_name = exe.c_str();
33
34 scoped_ptr<wchar_t, base::FreeDeleter> writable_command(
35 _wcsdup(command.c_str()));
36
37 // Create the process with the unicode version of the API.
38 sandbox::SboxTestResult ret1 = sandbox::SBOX_TEST_FAILED;
39 PROCESS_INFORMATION temp_process_info = {};
40 if (::CreateProcessW(exe_name,
41 command.empty() ? NULL : writable_command.get(),
42 NULL,
43 NULL,
44 FALSE,
45 0,
46 NULL,
47 NULL,
48 &si,
49 &temp_process_info)) {
50 pi.Set(temp_process_info);
51 ret1 = sandbox::SBOX_TEST_SUCCEEDED;
52 } else {
53 DWORD last_error = GetLastError();
54 if ((ERROR_NOT_ENOUGH_QUOTA == last_error) ||
55 (ERROR_ACCESS_DENIED == last_error) ||
56 (ERROR_FILE_NOT_FOUND == last_error)) {
57 ret1 = sandbox::SBOX_TEST_DENIED;
58 } else {
59 ret1 = sandbox::SBOX_TEST_FAILED;
60 }
61 }
62
63 pi.Close();
64
65 // Do the same with the ansi version of the api
66 STARTUPINFOA sia = {sizeof(sia)};
67 sandbox::SboxTestResult ret2 = sandbox::SBOX_TEST_FAILED;
68
69 std::string narrow_cmd_line =
70 base::SysWideToMultiByte(command.c_str(), CP_UTF8);
71 if (::CreateProcessA(
72 exe_name ? base::SysWideToMultiByte(exe_name, CP_UTF8).c_str() : NULL,
73 command.empty() ? NULL : &narrow_cmd_line[0],
74 NULL, NULL, FALSE, 0, NULL, NULL, &sia, &temp_process_info)) {
75 pi.Set(temp_process_info);
76 ret2 = sandbox::SBOX_TEST_SUCCEEDED;
77 } else {
78 DWORD last_error = GetLastError();
79 if ((ERROR_NOT_ENOUGH_QUOTA == last_error) ||
80 (ERROR_ACCESS_DENIED == last_error) ||
81 (ERROR_FILE_NOT_FOUND == last_error)) {
82 ret2 = sandbox::SBOX_TEST_DENIED;
83 } else {
84 ret2 = sandbox::SBOX_TEST_FAILED;
85 }
86 }
87
88 if (ret1 == ret2)
89 return ret1;
90
91 return sandbox::SBOX_TEST_FAILED;
92 }
93
94 } // namespace
95
96 namespace sandbox {
97
98 SBOX_TESTS_COMMAND int Process_RunApp1(int argc, wchar_t **argv) {
99 if (argc != 1) {
100 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
101 }
102 if ((NULL == argv) || (NULL == argv[0])) {
103 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
104 }
105 base::string16 path = MakePathToSys(argv[0], false);
106
107 // TEST 1: Try with the path in the app_name.
108 return CreateProcessHelper(path, base::string16());
109 }
110
111 SBOX_TESTS_COMMAND int Process_RunApp2(int argc, wchar_t **argv) {
112 if (argc != 1) {
113 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
114 }
115 if ((NULL == argv) || (NULL == argv[0])) {
116 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
117 }
118 base::string16 path = MakePathToSys(argv[0], false);
119
120 // TEST 2: Try with the path in the cmd_line.
121 base::string16 cmd_line = L"\"";
122 cmd_line += path;
123 cmd_line += L"\"";
124 return CreateProcessHelper(base::string16(), cmd_line);
125 }
126
127 SBOX_TESTS_COMMAND int Process_RunApp3(int argc, wchar_t **argv) {
128 if (argc != 1) {
129 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
130 }
131 if ((NULL == argv) || (NULL == argv[0])) {
132 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
133 }
134 // TEST 3: Try file name in the cmd_line.
135 return CreateProcessHelper(base::string16(), argv[0]);
136 }
137
138 SBOX_TESTS_COMMAND int Process_RunApp4(int argc, wchar_t **argv) {
139 if (argc != 1) {
140 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
141 }
142 if ((NULL == argv) || (NULL == argv[0])) {
143 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
144 }
145
146 // TEST 4: Try file name in the app_name and current directory sets correctly.
147 base::string16 system32 = MakePathToSys(L"", false);
148 wchar_t current_directory[MAX_PATH + 1];
149 DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory);
150 if (!ret)
151 return SBOX_TEST_FIRST_ERROR;
152 if (ret >= MAX_PATH)
153 return SBOX_TEST_FAILED;
154
155 current_directory[ret] = L'\\';
156 current_directory[ret+1] = L'\0';
157 if (!::SetCurrentDirectory(system32.c_str())) {
158 return SBOX_TEST_SECOND_ERROR;
159 }
160
161 const int result4 = CreateProcessHelper(argv[0], base::string16());
162 return ::SetCurrentDirectory(current_directory) ? result4 : SBOX_TEST_FAILED;
163 }
164
165 SBOX_TESTS_COMMAND int Process_RunApp5(int argc, wchar_t **argv) {
166 if (argc != 1) {
167 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
168 }
169 if ((NULL == argv) || (NULL == argv[0])) {
170 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
171 }
172 base::string16 path = MakePathToSys(argv[0], false);
173
174 // TEST 5: Try with the path in the cmd_line and arguments.
175 base::string16 cmd_line = L"\"";
176 cmd_line += path;
177 cmd_line += L"\" /I";
178 return CreateProcessHelper(base::string16(), cmd_line);
179 }
180
181 SBOX_TESTS_COMMAND int Process_RunApp6(int argc, wchar_t **argv) {
182 if (argc != 1) {
183 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
184 }
185 if ((NULL == argv) || (NULL == argv[0])) {
186 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
187 }
188
189 // TEST 6: Try with the file_name in the cmd_line and arguments.
190 base::string16 cmd_line = argv[0];
191 cmd_line += L" /I";
192 return CreateProcessHelper(base::string16(), cmd_line);
193 }
194
195 // Creates a process and checks if it's possible to get a handle to it's token.
196 SBOX_TESTS_COMMAND int Process_GetChildProcessToken(int argc, wchar_t **argv) {
197 if (argc != 1)
198 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
199
200 if ((NULL == argv) || (NULL == argv[0]))
201 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
202
203 base::string16 path = MakePathToSys(argv[0], false);
204
205 STARTUPINFOW si = {sizeof(si)};
206
207 PROCESS_INFORMATION temp_process_info = {};
208 if (!::CreateProcessW(path.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED,
209 NULL, NULL, &si, &temp_process_info)) {
210 return SBOX_TEST_FAILED;
211 }
212 base::win::ScopedProcessInformation pi(temp_process_info);
213
214 HANDLE token = NULL;
215 BOOL result =
216 ::OpenProcessToken(pi.process_handle(), TOKEN_IMPERSONATE, &token);
217 DWORD error = ::GetLastError();
218
219 base::win::ScopedHandle token_handle(token);
220
221 if (!::TerminateProcess(pi.process_handle(), 0))
222 return SBOX_TEST_FAILED;
223
224 if (result && token)
225 return SBOX_TEST_SUCCEEDED;
226
227 if (ERROR_ACCESS_DENIED == error)
228 return SBOX_TEST_DENIED;
229
230 return SBOX_TEST_FAILED;
231 }
232
233 // Creates a suspended process using CreateProcessA then kill it.
234 SBOX_TESTS_COMMAND int Process_CreateProcessA(int argc, wchar_t** argv) {
235 if (argc != 1)
236 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
237
238 if ((NULL == argv) || (NULL == argv[0]))
239 return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
240
241 STARTUPINFOA si = {sizeof(si)};
242
243 base::string16 path = MakePathToSys(argv[0], false);
244
245 PROCESS_INFORMATION temp_process_info = {};
246 // Create suspended to avoid popping calc.
247 if (!::CreateProcessA(base::SysWideToMultiByte(path, CP_UTF8).c_str(), NULL,
248 NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si,
249 &temp_process_info)) {
250 return SBOX_TEST_FAILED;
251 }
252 base::win::ScopedProcessInformation pi(temp_process_info);
253
254 if (!::TerminateProcess(pi.process_handle(), 0))
255 return SBOX_TEST_FAILED;
256
257 return SBOX_TEST_SUCCEEDED;
258 }
259
260 SBOX_TESTS_COMMAND int Process_OpenToken(int argc, wchar_t **argv) {
261 HANDLE token;
262 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
263 if (ERROR_ACCESS_DENIED == ::GetLastError()) {
264 return SBOX_TEST_DENIED;
265 }
266 } else {
267 ::CloseHandle(token);
268 return SBOX_TEST_SUCCEEDED;
269 }
270
271 return SBOX_TEST_FAILED;
272 }
273
274 SBOX_TESTS_COMMAND int Process_Crash(int argc, wchar_t **argv) {
275 __debugbreak();
276 return SBOX_TEST_FAILED;
277 }
278 // Generate a event name, used to test thread creation.
279 std::wstring GenerateEventName(DWORD pid) {
280 wchar_t buff[30] = {0};
281 int res = swprintf_s(buff, sizeof(buff) / sizeof(buff[0]),
282 L"ProcessPolicyTest_%08x", pid);
283 if (-1 != res) {
284 return std::wstring(buff);
285 }
286 return std::wstring();
287 }
288
289 // This is the function that is called when testing thread creation.
290 // It is expected to set an event that the caller is waiting on.
291 DWORD WINAPI TestThreadFunc(LPVOID lpdwThreadParam) {
292 std::wstring event_name = GenerateEventName(
293 static_cast<DWORD>(reinterpret_cast<uintptr_t>(lpdwThreadParam)));
294 if (!event_name.length()) {
295 return 1;
296 }
297 HANDLE event = ::OpenEvent(EVENT_ALL_ACCESS | EVENT_MODIFY_STATE, FALSE,
298 event_name.c_str());
299 if (!event) {
300 return 1;
301 }
302 if (!SetEvent(event)) {
303 return 1;
304 }
305 return 0;
306 }
307
308 SBOX_TESTS_COMMAND int Process_CreateThread(int argc, wchar_t** argv) {
309 DWORD pid = ::GetCurrentProcessId();
310 std::wstring event_name = GenerateEventName(pid);
311 if (!event_name.length()) {
312 return SBOX_TEST_FIRST_ERROR;
313 }
314 HANDLE event = ::CreateEvent(NULL, TRUE, FALSE, event_name.c_str());
315 if (!event) {
316 return SBOX_TEST_SECOND_ERROR;
317 }
318
319 DWORD thread_id = 0;
320 HANDLE thread = NULL;
321 thread = ::CreateThread(NULL, 0, &TestThreadFunc,
322 reinterpret_cast<LPVOID>(static_cast<uintptr_t>(pid)),
323 0, &thread_id);
324
325 if (!thread) {
326 return SBOX_TEST_THIRD_ERROR;
327 }
328 if (!thread_id) {
329 return SBOX_TEST_FOURTH_ERROR;
330 }
331 if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
332 return SBOX_TEST_FIFTH_ERROR;
333 }
334 DWORD exit_code = 0;
335 if (!GetExitCodeThread(thread, &exit_code)) {
336 return SBOX_TEST_SIXTH_ERROR;
337 }
338 if (exit_code) {
339 return SBOX_TEST_SEVENTH_ERROR;
340 }
341 if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
342 return SBOX_TEST_FAILED;
343 }
344 return SBOX_TEST_SUCCEEDED;
345 }
346
347 TEST(ProcessPolicyTest, TestAllAccess) {
348 // Check if the "all access" rule fails to be added when the token is too
349 // powerful.
350 TestRunner runner;
351
352 // Check the failing case.
353 runner.GetPolicy()->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN);
354 EXPECT_EQ(SBOX_ERROR_UNSUPPORTED,
355 runner.GetPolicy()->AddRule(TargetPolicy::SUBSYS_PROCESS,
356 TargetPolicy::PROCESS_ALL_EXEC,
357 L"this is not important"));
358
359 // Check the working case.
360 runner.GetPolicy()->SetTokenLevel(USER_INTERACTIVE, USER_INTERACTIVE);
361
362 EXPECT_EQ(SBOX_ALL_OK,
363 runner.GetPolicy()->AddRule(TargetPolicy::SUBSYS_PROCESS,
364 TargetPolicy::PROCESS_ALL_EXEC,
365 L"this is not important"));
366 }
367
368 TEST(ProcessPolicyTest, CreateProcessAW) {
369 TestRunner runner;
370 base::string16 maybe_virtual_exe_path = MakePathToSys(L"findstr.exe", false);
371 base::string16 non_virtual_exe_path = MakePathToSys32(L"findstr.exe", false);
372 ASSERT_TRUE(!maybe_virtual_exe_path.empty());
373
374 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
375 TargetPolicy::PROCESS_MIN_EXEC,
376 maybe_virtual_exe_path.c_str()));
377
378 if (non_virtual_exe_path != maybe_virtual_exe_path) {
379 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
380 TargetPolicy::PROCESS_MIN_EXEC,
381 non_virtual_exe_path.c_str()));
382 }
383
384 // Need to add directory rules for the directories that we use in
385 // SetCurrentDirectory.
386 EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_DIR_ANY, L""));
387
388 wchar_t current_directory[MAX_PATH];
389 DWORD ret = ::GetCurrentDirectory(MAX_PATH, current_directory);
390 ASSERT_TRUE(0 != ret && ret < MAX_PATH);
391
392 wcscat_s(current_directory, MAX_PATH, L"\\");
393 EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_DIR_ANY,
394 current_directory));
395
396 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp1 calc.exe"));
397 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp2 calc.exe"));
398 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp3 calc.exe"));
399 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp4 calc.exe"));
400 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp5 calc.exe"));
401 EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"Process_RunApp6 calc.exe"));
402
403 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
404 runner.RunTest(L"Process_RunApp1 findstr.exe"));
405 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
406 runner.RunTest(L"Process_RunApp2 findstr.exe"));
407 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
408 runner.RunTest(L"Process_RunApp3 findstr.exe"));
409 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
410 runner.RunTest(L"Process_RunApp4 findstr.exe"));
411 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
412 runner.RunTest(L"Process_RunApp5 findstr.exe"));
413 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
414 runner.RunTest(L"Process_RunApp6 findstr.exe"));
415 }
416
417 // Tests that the broker correctly handles a process crashing within the job.
418 TEST(ProcessPolicyTest, CreateProcessCrashy) {
419 TestRunner runner;
420 EXPECT_EQ(static_cast<int>(STATUS_BREAKPOINT),
421 runner.RunTest(L"Process_Crash"));
422 }
423
424 TEST(ProcessPolicyTest, OpenToken) {
425 TestRunner runner;
426 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_OpenToken"));
427 }
428
429 TEST(ProcessPolicyTest, TestGetProcessTokenMinAccess) {
430 TestRunner runner;
431 base::string16 exe_path = MakePathToSys(L"findstr.exe", false);
432 ASSERT_TRUE(!exe_path.empty());
433 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
434 TargetPolicy::PROCESS_MIN_EXEC,
435 exe_path.c_str()));
436
437 EXPECT_EQ(SBOX_TEST_DENIED,
438 runner.RunTest(L"Process_GetChildProcessToken findstr.exe"));
439 }
440
441 TEST(ProcessPolicyTest, TestGetProcessTokenMaxAccess) {
442 TestRunner runner(JOB_UNPROTECTED, USER_INTERACTIVE, USER_INTERACTIVE);
443 base::string16 exe_path = MakePathToSys(L"findstr.exe", false);
444 ASSERT_TRUE(!exe_path.empty());
445 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
446 TargetPolicy::PROCESS_ALL_EXEC,
447 exe_path.c_str()));
448
449 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
450 runner.RunTest(L"Process_GetChildProcessToken findstr.exe"));
451 }
452
453 TEST(ProcessPolicyTest, TestGetProcessTokenMinAccessNoJob) {
454 TestRunner runner(JOB_NONE, USER_RESTRICTED_SAME_ACCESS, USER_LOCKDOWN);
455 base::string16 exe_path = MakePathToSys(L"findstr.exe", false);
456 ASSERT_TRUE(!exe_path.empty());
457 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
458 TargetPolicy::PROCESS_MIN_EXEC,
459 exe_path.c_str()));
460
461 EXPECT_EQ(SBOX_TEST_DENIED,
462 runner.RunTest(L"Process_GetChildProcessToken findstr.exe"));
463 }
464
465 TEST(ProcessPolicyTest, TestGetProcessTokenMaxAccessNoJob) {
466 TestRunner runner(JOB_NONE, USER_INTERACTIVE, USER_INTERACTIVE);
467 base::string16 exe_path = MakePathToSys(L"findstr.exe", false);
468 ASSERT_TRUE(!exe_path.empty());
469 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
470 TargetPolicy::PROCESS_ALL_EXEC,
471 exe_path.c_str()));
472
473 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
474 runner.RunTest(L"Process_GetChildProcessToken findstr.exe"));
475 }
476
477 TEST(ProcessPolicyTest, TestCreateProcessA) {
478 TestRunner runner;
479 sandbox::TargetPolicy* policy = runner.GetPolicy();
480 policy->SetJobLevel(JOB_NONE, 0);
481 policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
482 base::string16 exe_path = MakePathToSys(L"calc.exe", false);
483 ASSERT_TRUE(!exe_path.empty());
484 EXPECT_TRUE(runner.AddRule(TargetPolicy::SUBSYS_PROCESS,
485 TargetPolicy::PROCESS_ALL_EXEC, exe_path.c_str()));
486 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
487 runner.RunTest(L"Process_CreateProcessA calc.exe"));
488 }
489
490 // This tests that the CreateThread works with CSRSS not locked down.
491 // In other words, that the interception passes through OK.
492 TEST(ProcessPolicyTest, TestCreateThreadWithCsrss) {
493 TestRunner runner(JOB_NONE, USER_INTERACTIVE, USER_INTERACTIVE);
494 runner.SetDisableCsrss(false);
495 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_CreateThread"));
496 }
497
498 // This tests that the CreateThread works with CSRSS locked down.
499 // In other words, that the interception correctly works.
500 TEST(ProcessPolicyTest, TestCreateThreadWithoutCsrss) {
501 TestRunner runner(JOB_NONE, USER_INTERACTIVE, USER_INTERACTIVE);
502 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"Process_CreateThread"));
503 }
504
505 // This tests that our CreateThread interceptors works when called directly.
506 TEST(ProcessPolicyTest, TestCreateThreadOutsideSandbox) {
507 DWORD pid = ::GetCurrentProcessId();
508 std::wstring event_name = GenerateEventName(pid);
509 ASSERT_STRNE(NULL, event_name.c_str());
510 HANDLE event = ::CreateEvent(NULL, TRUE, FALSE, event_name.c_str());
511 EXPECT_NE(static_cast<HANDLE>(NULL), event);
512
513 DWORD thread_id = 0;
514 HANDLE thread = NULL;
515 thread = TargetCreateThread(
516 ::CreateThread, NULL, 0, &TestThreadFunc,
517 reinterpret_cast<LPVOID>(static_cast<uintptr_t>(pid)), 0, &thread_id);
518 EXPECT_NE(static_cast<HANDLE>(NULL), thread);
519 EXPECT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE));
520 EXPECT_EQ(WAIT_OBJECT_0, WaitForSingleObject(event, INFINITE));
521 }
522
523 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/process_mitigations_win32k_policy.cc ('k') | sandbox/win/src/process_thread_dispatcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698