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

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

Issue 919893002: Replace handles that the handle closer closes with dummy Events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add comment Created 5 years, 10 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
« no previous file with comments | « sandbox/win/src/handle_closer_agent.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/strings/stringprintf.h" 5 #include "base/strings/stringprintf.h"
6 #include "base/win/scoped_handle.h" 6 #include "base/win/scoped_handle.h"
7 #include "sandbox/win/src/handle_closer_agent.h" 7 #include "sandbox/win/src/handle_closer_agent.h"
8 #include "sandbox/win/src/nt_internals.h"
8 #include "sandbox/win/src/sandbox.h" 9 #include "sandbox/win/src/sandbox.h"
9 #include "sandbox/win/src/sandbox_factory.h" 10 #include "sandbox/win/src/sandbox_factory.h"
10 #include "sandbox/win/src/target_services.h" 11 #include "sandbox/win/src/target_services.h"
11 #include "sandbox/win/tests/common/controller.h" 12 #include "sandbox/win/tests/common/controller.h"
12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "testing/gtest/include/gtest/gtest.h"
13 14
14 namespace { 15 namespace {
15 16
16 const wchar_t *kFileExtensions[] = { L".1", L".2", L".3", L".4" }; 17 const wchar_t *kFileExtensions[] = { L".1", L".2", L".3", L".4" };
17 18
(...skipping 17 matching lines...) Expand all
35 timestamp.dwLowDateTime, 36 timestamp.dwLowDateTime,
36 timestamp.dwHighDateTime); 37 timestamp.dwHighDateTime);
37 marker_path += extension; 38 marker_path += extension;
38 39
39 // Make the file delete-on-close so cleanup is automatic. 40 // Make the file delete-on-close so cleanup is automatic.
40 return CreateFile(marker_path.c_str(), FILE_ALL_ACCESS, 41 return CreateFile(marker_path.c_str(), FILE_ALL_ACCESS,
41 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 42 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
42 NULL, OPEN_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); 43 NULL, OPEN_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
43 } 44 }
44 45
46 // Returns type infomation for an NT object. This routine is expected to be
47 // called for invalid handles so it catches STATUS_INVALID_HANDLE exceptions
48 // that can be generated when handle tracing is enabled.
49 NTSTATUS QueryObjectTypeInformation(HANDLE handle, void* buffer, ULONG* size) {
50 static NtQueryObject QueryObject = NULL;
51 if (!QueryObject)
52 ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
53
54 NTSTATUS status = STATUS_UNSUCCESSFUL;
55 __try {
56 status = QueryObject(handle, ObjectTypeInformation, buffer, *size, size);
57 }
58 __except(GetExceptionCode() == STATUS_INVALID_HANDLE
59 ? EXCEPTION_EXECUTE_HANDLER
60 : EXCEPTION_CONTINUE_SEARCH) {
61 status = STATUS_INVALID_HANDLE;
62 }
63 return status;
64 }
65
45 // Used by the thread pool tests. 66 // Used by the thread pool tests.
46 HANDLE finish_event; 67 HANDLE finish_event;
47 const int kWaitCount = 20; 68 const int kWaitCount = 20;
48 69
49 } // namespace 70 } // namespace
50 71
51 namespace sandbox { 72 namespace sandbox {
52 73
53 // Checks for the presence of a list of files (in object path form). 74 // Checks for the presence of a list of files (in object path form).
54 // Format: CheckForFileHandle (Y|N) \path\to\file1 [\path\to\file2 ...] 75 // Format: CheckForFileHandle (Y|N) \path\to\file1 [\path\to\file2 ...]
55 // - Y or N depending if the file should exist or not. 76 // - Y or N depending if the file should exist or not.
56 SBOX_TESTS_COMMAND int CheckForFileHandles(int argc, wchar_t **argv) { 77 SBOX_TESTS_COMMAND int CheckForFileHandles(int argc, wchar_t **argv) {
57 if (argc < 2) 78 if (argc < 2)
58 return SBOX_TEST_FAILED_TO_RUN_TEST; 79 return SBOX_TEST_FAILED_TO_RUN_TEST;
59 bool should_find = argv[0][0] == L'Y'; 80 bool should_find = argv[0][0] == L'Y';
60 if (argv[0][1] != L'\0' || !should_find && argv[0][0] != L'N') 81 if (argv[0][1] != L'\0' || !should_find && argv[0][0] != L'N')
61 return SBOX_TEST_FAILED_TO_RUN_TEST; 82 return SBOX_TEST_FAILED_TO_RUN_TEST;
62 83
63 static int state = BEFORE_INIT; 84 static int state = BEFORE_INIT;
64 switch (state++) { 85 switch (state++) {
65 case BEFORE_INIT: 86 case BEFORE_INIT:
66 // Create a unique marker file that is open while the test is running. 87 // Create a unique marker file that is open while the test is running.
67 // The handles leak, but it will be closed by the test or on exit. 88 // The handles leak, but it will be closed by the test or on exit.
68 for (int i = 0; i < arraysize(kFileExtensions); ++i) 89 for (int i = 0; i < arraysize(kFileExtensions); ++i)
69 EXPECT_NE(GetMarkerFile(kFileExtensions[i]), INVALID_HANDLE_VALUE); 90 CHECK_NE(GetMarkerFile(kFileExtensions[i]), INVALID_HANDLE_VALUE);
70 return SBOX_TEST_SUCCEEDED; 91 return SBOX_TEST_SUCCEEDED;
71 92
72 case AFTER_REVERT: { 93 case AFTER_REVERT: {
73 // Brute force the handle table to find what we're looking for. 94 // Brute force the handle table to find what we're looking for.
74 DWORD handle_count = UINT_MAX; 95 DWORD handle_count = UINT_MAX;
75 const int kInvalidHandleThreshold = 100; 96 const int kInvalidHandleThreshold = 100;
76 const size_t kHandleOffset = 4; // Handles are always a multiple of 4. 97 const size_t kHandleOffset = 4; // Handles are always a multiple of 4.
77 HANDLE handle = NULL; 98 HANDLE handle = NULL;
78 int invalid_count = 0; 99 int invalid_count = 0;
79 base::string16 handle_name; 100 base::string16 handle_name;
(...skipping 17 matching lines...) Expand all
97 return should_find ? SBOX_TEST_FAILED : SBOX_TEST_SUCCEEDED; 118 return should_find ? SBOX_TEST_FAILED : SBOX_TEST_SUCCEEDED;
98 } 119 }
99 120
100 default: // Do nothing. 121 default: // Do nothing.
101 break; 122 break;
102 } 123 }
103 124
104 return SBOX_TEST_SUCCEEDED; 125 return SBOX_TEST_SUCCEEDED;
105 } 126 }
106 127
128 // Checks that supplied handle is an Event and it's not waitable.
129 // Format: CheckForEventHandles
130 SBOX_TESTS_COMMAND int CheckForEventHandles(int argc, wchar_t** argv) {
131 static int state = BEFORE_INIT;
132 static std::vector<HANDLE> to_check;
133
134 switch (state++) {
135 case BEFORE_INIT:
136 // Create a unique marker file that is open while the test is running.
137 for (int i = 0; i < arraysize(kFileExtensions); ++i) {
138 HANDLE handle = GetMarkerFile(kFileExtensions[i]);
139 CHECK_NE(handle, INVALID_HANDLE_VALUE);
140 to_check.push_back(handle);
141 }
142 return SBOX_TEST_SUCCEEDED;
143
144 case AFTER_REVERT:
145 for (auto handle : to_check) {
146 // Set up buffers for the type info and the name.
147 std::vector<BYTE> type_info_buffer(sizeof(OBJECT_TYPE_INFORMATION) +
148 32 * sizeof(wchar_t));
149 OBJECT_TYPE_INFORMATION* type_info =
150 reinterpret_cast<OBJECT_TYPE_INFORMATION*>(&(type_info_buffer[0]));
151 NTSTATUS rc;
152
153 // Get the type name, reusing the buffer.
154 ULONG size = static_cast<ULONG>(type_info_buffer.size());
155 rc = QueryObjectTypeInformation(handle, type_info, &size);
156 while (rc == STATUS_INFO_LENGTH_MISMATCH ||
157 rc == STATUS_BUFFER_OVERFLOW) {
158 type_info_buffer.resize(size + sizeof(wchar_t));
159 type_info = reinterpret_cast<OBJECT_TYPE_INFORMATION*>(
160 &(type_info_buffer[0]));
161 rc = QueryObjectTypeInformation(handle, type_info, &size);
162 // Leave padding for the nul terminator.
163 if (NT_SUCCESS(rc) && size == type_info_buffer.size())
164 rc = STATUS_INFO_LENGTH_MISMATCH;
165 }
166
167 CHECK(NT_SUCCESS(rc));
168 CHECK(type_info->Name.Buffer);
169
170 type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] =
171 L'\0';
172
173 // Should be an Event now.
174 CHECK_EQ(wcslen(type_info->Name.Buffer), 5U);
175 CHECK_EQ(wcscmp(L"Event", type_info->Name.Buffer), 0);
176
177 // Should not be able to wait.
178 CHECK_EQ(WaitForSingleObject(handle, INFINITE), WAIT_FAILED);
179
180 // Should be able to close.
181 CHECK_EQ(TRUE, CloseHandle(handle));
182 }
183 return SBOX_TEST_SUCCEEDED;
184
185 default: // Do nothing.
186 break;
187 }
188
189 return SBOX_TEST_SUCCEEDED;
190 }
191
107 TEST(HandleCloserTest, CheckForMarkerFiles) { 192 TEST(HandleCloserTest, CheckForMarkerFiles) {
108 TestRunner runner; 193 TestRunner runner;
109 runner.SetTimeout(2000); 194 runner.SetTimeout(2000);
110 runner.SetTestState(EVERY_STATE); 195 runner.SetTestState(EVERY_STATE);
111 196
112 base::string16 command = base::string16(L"CheckForFileHandles Y"); 197 base::string16 command = base::string16(L"CheckForFileHandles Y");
113 for (int i = 0; i < arraysize(kFileExtensions); ++i) { 198 for (int i = 0; i < arraysize(kFileExtensions); ++i) {
114 base::string16 handle_name; 199 base::string16 handle_name;
115 base::win::ScopedHandle marker(GetMarkerFile(kFileExtensions[i])); 200 base::win::ScopedHandle marker(GetMarkerFile(kFileExtensions[i]));
116 CHECK(marker.IsValid()); 201 CHECK(marker.IsValid());
(...skipping 21 matching lines...) Expand all
138 CHECK_EQ(policy->AddKernelObjectToClose(L"File", handle_name.c_str()), 223 CHECK_EQ(policy->AddKernelObjectToClose(L"File", handle_name.c_str()),
139 SBOX_ALL_OK); 224 SBOX_ALL_OK);
140 command += (L" "); 225 command += (L" ");
141 command += handle_name; 226 command += handle_name;
142 } 227 }
143 228
144 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command.c_str())) << 229 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command.c_str())) <<
145 "Failed: " << command; 230 "Failed: " << command;
146 } 231 }
147 232
233 TEST(HandleCloserTest, CheckStuffedHandle) {
234 TestRunner runner;
235 runner.SetTimeout(2000);
236 runner.SetTestState(EVERY_STATE);
237 sandbox::TargetPolicy* policy = runner.GetPolicy();
238
239 for (int i = 0; i < arraysize(kFileExtensions); ++i) {
240 base::string16 handle_name;
241 base::win::ScopedHandle marker(GetMarkerFile(kFileExtensions[i]));
242 CHECK(marker.IsValid());
243 CHECK(sandbox::GetHandleName(marker.Get(), &handle_name));
244 CHECK_EQ(policy->AddKernelObjectToClose(L"File", handle_name.c_str()),
245 SBOX_ALL_OK);
246 }
247
248 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckForEventHandles"));
249 }
250
148 void WINAPI ThreadPoolTask(void* event, BOOLEAN timeout) { 251 void WINAPI ThreadPoolTask(void* event, BOOLEAN timeout) {
149 static volatile LONG waiters_remaining = kWaitCount; 252 static volatile LONG waiters_remaining = kWaitCount;
150 CHECK(!timeout); 253 CHECK(!timeout);
151 CHECK(::CloseHandle(event)); 254 CHECK(::CloseHandle(event));
152 if (::InterlockedDecrement(&waiters_remaining) == 0) 255 if (::InterlockedDecrement(&waiters_remaining) == 0)
153 CHECK(::SetEvent(finish_event)); 256 CHECK(::SetEvent(finish_event));
154 } 257 }
155 258
156 // Run a thread pool inside a sandbox without a CSRSS connection. 259 // Run a thread pool inside a sandbox without a CSRSS connection.
157 SBOX_TESTS_COMMAND int RunThreadPool(int argc, wchar_t **argv) { 260 SBOX_TESTS_COMMAND int RunThreadPool(int argc, wchar_t **argv) {
(...skipping 27 matching lines...) Expand all
185 runner.SetTestState(AFTER_REVERT); 288 runner.SetTestState(AFTER_REVERT);
186 sandbox::TargetPolicy* policy = runner.GetPolicy(); 289 sandbox::TargetPolicy* policy = runner.GetPolicy();
187 290
188 // Sever the CSRSS connection by closing ALPC ports inside the sandbox. 291 // Sever the CSRSS connection by closing ALPC ports inside the sandbox.
189 CHECK_EQ(policy->AddKernelObjectToClose(L"ALPC Port", NULL), SBOX_ALL_OK); 292 CHECK_EQ(policy->AddKernelObjectToClose(L"ALPC Port", NULL), SBOX_ALL_OK);
190 293
191 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"RunThreadPool")); 294 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"RunThreadPool"));
192 } 295 }
193 296
194 } // namespace sandbox 297 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/handle_closer_agent.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698