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

Side by Side Diff: sandbox/win/src/interception_unittest.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
« no previous file with comments | « sandbox/win/src/interception_internal.h ('k') | sandbox/win/src/interceptors.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 // This file contains unit tests for InterceptionManager.
6 // The tests require private information so the whole interception.cc file is
7 // included from this file.
8
9 #include <windows.h>
10 #include <stddef.h>
11
12 #include <algorithm>
13 #include <set>
14
15 #include "base/bits.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "sandbox/win/src/interception.h"
18 #include "sandbox/win/src/interception_internal.h"
19 #include "sandbox/win/src/interceptors.h"
20 #include "sandbox/win/src/target_process.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace sandbox {
24
25 namespace internal {
26 size_t GetGranularAlignedRandomOffset(size_t size);
27 }
28
29 // Walks the settings buffer, verifying that the values make sense and counting
30 // objects.
31 // Arguments:
32 // buffer (in): the buffer to walk.
33 // size (in): buffer size
34 // num_dlls (out): count of the dlls on the buffer.
35 // num_function (out): count of intercepted functions.
36 // num_names (out): count of named interceptor functions.
37 void WalkBuffer(void* buffer, size_t size, int* num_dlls, int* num_functions,
38 int* num_names) {
39 ASSERT_TRUE(NULL != buffer);
40 ASSERT_TRUE(NULL != num_functions);
41 ASSERT_TRUE(NULL != num_names);
42 *num_dlls = *num_functions = *num_names = 0;
43 SharedMemory *memory = reinterpret_cast<SharedMemory*>(buffer);
44
45 ASSERT_GT(size, sizeof(SharedMemory));
46 DllPatchInfo *dll = &memory->dll_list[0];
47
48 for (int i = 0; i < memory->num_intercepted_dlls; i++) {
49 ASSERT_NE(0u, wcslen(dll->dll_name));
50 ASSERT_EQ(0u, dll->record_bytes % sizeof(size_t));
51 ASSERT_EQ(0u, dll->offset_to_functions % sizeof(size_t));
52 ASSERT_NE(0, dll->num_functions);
53
54 FunctionInfo *function = reinterpret_cast<FunctionInfo*>(
55 reinterpret_cast<char*>(dll) + dll->offset_to_functions);
56
57 for (int j = 0; j < dll->num_functions; j++) {
58 ASSERT_EQ(0u, function->record_bytes % sizeof(size_t));
59
60 char* name = function->function;
61 size_t length = strlen(name);
62 ASSERT_NE(0u, length);
63 name += length + 1;
64
65 // look for overflows
66 ASSERT_GT(reinterpret_cast<char*>(buffer) + size, name + strlen(name));
67
68 // look for a named interceptor
69 if (strlen(name)) {
70 (*num_names)++;
71 EXPECT_TRUE(NULL == function->interceptor_address);
72 } else {
73 EXPECT_TRUE(NULL != function->interceptor_address);
74 }
75
76 (*num_functions)++;
77 function = reinterpret_cast<FunctionInfo*>(
78 reinterpret_cast<char*>(function) + function->record_bytes);
79 }
80
81 (*num_dlls)++;
82 dll = reinterpret_cast<DllPatchInfo*>(reinterpret_cast<char*>(dll) +
83 dll->record_bytes);
84 }
85 }
86
87 TEST(InterceptionManagerTest, GetGranularAlignedRandomOffset) {
88 std::set<size_t> sizes;
89
90 // 544 is current value of interceptions_.size() * sizeof(ThunkData) +
91 // sizeof(DllInterceptionData).
92 const size_t kThunkBytes = 544;
93
94 // ciel(log2(544)) = 10.
95 // Alignment must be 2^10 = 1024.
96 const size_t kAlignmentBits = base::bits::Log2Ceiling(kThunkBytes);
97 const size_t kAlignment = static_cast<size_t>(1) << kAlignmentBits;
98
99 const size_t kAllocGranularity = 65536;
100
101 // Generate enough sample data to ensure there is at least one value in each
102 // potential bucket.
103 for (size_t i = 0; i < 1000000; i++)
104 sizes.insert(internal::GetGranularAlignedRandomOffset(kThunkBytes));
105
106 size_t prev_val = 0;
107 size_t min_val = kAllocGranularity;
108 size_t min_nonzero_val = kAllocGranularity;
109 size_t max_val = 0;
110
111 for (size_t val : sizes) {
112 ASSERT_LT(val, kAllocGranularity);
113 if (prev_val)
114 ASSERT_EQ(val - prev_val, kAlignment);
115 if (val)
116 min_nonzero_val = std::min(val, min_nonzero_val);
117 min_val = std::min(val, min_val);
118 prev_val = val;
119 max_val = std::max(val, max_val);
120 }
121 ASSERT_EQ(max_val, kAllocGranularity - kAlignment);
122 ASSERT_EQ(0u, min_val);
123 ASSERT_EQ(min_nonzero_val, kAlignment);
124 }
125
126 TEST(InterceptionManagerTest, BufferLayout1) {
127 wchar_t exe_name[MAX_PATH];
128 ASSERT_NE(0u, GetModuleFileName(NULL, exe_name, MAX_PATH - 1));
129
130 TargetProcess *target = MakeTestTargetProcess(::GetCurrentProcess(),
131 ::GetModuleHandle(exe_name));
132
133 InterceptionManager interceptions(target, true);
134
135 // Any pointer will do for a function pointer.
136 void* function = &interceptions;
137
138 // We don't care about the interceptor id.
139 interceptions.AddToPatchedFunctions(L"ntdll.dll", "NtCreateFile",
140 INTERCEPTION_SERVICE_CALL, function,
141 OPEN_KEY_ID);
142 interceptions.AddToPatchedFunctions(L"kernel32.dll", "CreateFileEx",
143 INTERCEPTION_EAT, function, OPEN_KEY_ID);
144 interceptions.AddToPatchedFunctions(L"kernel32.dll", "SomeFileEx",
145 INTERCEPTION_SMART_SIDESTEP, function,
146 OPEN_KEY_ID);
147 interceptions.AddToPatchedFunctions(L"user32.dll", "FindWindow",
148 INTERCEPTION_EAT, function, OPEN_KEY_ID);
149 interceptions.AddToPatchedFunctions(L"kernel32.dll", "CreateMutex",
150 INTERCEPTION_EAT, function, OPEN_KEY_ID);
151 interceptions.AddToPatchedFunctions(L"user32.dll", "PostMsg",
152 INTERCEPTION_EAT, function, OPEN_KEY_ID);
153 interceptions.AddToPatchedFunctions(L"user32.dll", "PostMsg",
154 INTERCEPTION_EAT, "replacement",
155 OPEN_KEY_ID);
156 interceptions.AddToPatchedFunctions(L"comctl.dll", "SaveAsDlg",
157 INTERCEPTION_EAT, function, OPEN_KEY_ID);
158 interceptions.AddToPatchedFunctions(L"ntdll.dll", "NtClose",
159 INTERCEPTION_SERVICE_CALL, function,
160 OPEN_KEY_ID);
161 interceptions.AddToPatchedFunctions(L"ntdll.dll", "NtOpenFile",
162 INTERCEPTION_SIDESTEP, function,
163 OPEN_KEY_ID);
164 interceptions.AddToPatchedFunctions(L"some.dll", "Superfn",
165 INTERCEPTION_EAT, function, OPEN_KEY_ID);
166 interceptions.AddToPatchedFunctions(L"comctl.dll", "SaveAsDlg",
167 INTERCEPTION_EAT, "a", OPEN_KEY_ID);
168 interceptions.AddToPatchedFunctions(L"comctl.dll", "SaveAsDlg",
169 INTERCEPTION_SIDESTEP, "ab", OPEN_KEY_ID);
170 interceptions.AddToPatchedFunctions(L"comctl.dll", "SaveAsDlg",
171 INTERCEPTION_EAT, "abc", OPEN_KEY_ID);
172 interceptions.AddToPatchedFunctions(L"a.dll", "p",
173 INTERCEPTION_EAT, function, OPEN_KEY_ID);
174 interceptions.AddToPatchedFunctions(L"b.dll",
175 "TheIncredibleCallToSaveTheWorld",
176 INTERCEPTION_EAT, function, OPEN_KEY_ID);
177 interceptions.AddToPatchedFunctions(L"a.dll", "BIsLame",
178 INTERCEPTION_EAT, function, OPEN_KEY_ID);
179 interceptions.AddToPatchedFunctions(L"a.dll", "ARules",
180 INTERCEPTION_EAT, function, OPEN_KEY_ID);
181
182 // Verify that all interceptions were added
183 ASSERT_EQ(18u, interceptions.interceptions_.size());
184
185 size_t buffer_size = interceptions.GetBufferSize();
186 scoped_ptr<BYTE[]> local_buffer(new BYTE[buffer_size]);
187
188 ASSERT_TRUE(interceptions.SetupConfigBuffer(local_buffer.get(),
189 buffer_size));
190
191 // At this point, the interceptions should have been separated into two
192 // groups: one group with the local ("cold") interceptions, consisting of
193 // everything from ntdll and stuff set as INTRECEPTION_SERVICE_CALL, and
194 // another group with the interceptions belonging to dlls that will be "hot"
195 // patched on the client. The second group lives on local_buffer, and the
196 // first group remains on the list of interceptions (inside the object
197 // "interceptions"). There are 3 local interceptions (of ntdll); the
198 // other 15 have to be sent to the child to be performed "hot".
199 EXPECT_EQ(3u, interceptions.interceptions_.size());
200
201 int num_dlls, num_functions, num_names;
202 WalkBuffer(local_buffer.get(), buffer_size, &num_dlls, &num_functions,
203 &num_names);
204
205 // The 15 interceptions on the buffer (to the child) should be grouped on 6
206 // dlls. Only four interceptions are using an explicit name for the
207 // interceptor function.
208 EXPECT_EQ(6, num_dlls);
209 EXPECT_EQ(15, num_functions);
210 EXPECT_EQ(4, num_names);
211 }
212
213 TEST(InterceptionManagerTest, BufferLayout2) {
214 wchar_t exe_name[MAX_PATH];
215 ASSERT_NE(0u, GetModuleFileName(NULL, exe_name, MAX_PATH - 1));
216
217 TargetProcess *target = MakeTestTargetProcess(::GetCurrentProcess(),
218 ::GetModuleHandle(exe_name));
219
220 InterceptionManager interceptions(target, true);
221
222 // Any pointer will do for a function pointer.
223 void* function = &interceptions;
224 interceptions.AddToUnloadModules(L"some01.dll");
225 // We don't care about the interceptor id.
226 interceptions.AddToPatchedFunctions(L"ntdll.dll", "NtCreateFile",
227 INTERCEPTION_SERVICE_CALL, function,
228 OPEN_FILE_ID);
229 interceptions.AddToPatchedFunctions(L"kernel32.dll", "CreateFileEx",
230 INTERCEPTION_EAT, function, OPEN_FILE_ID);
231 interceptions.AddToUnloadModules(L"some02.dll");
232 interceptions.AddToPatchedFunctions(L"kernel32.dll", "SomeFileEx",
233 INTERCEPTION_SMART_SIDESTEP, function,
234 OPEN_FILE_ID);
235 // Verify that all interceptions were added
236 ASSERT_EQ(5u, interceptions.interceptions_.size());
237
238 size_t buffer_size = interceptions.GetBufferSize();
239 scoped_ptr<BYTE[]> local_buffer(new BYTE[buffer_size]);
240
241 ASSERT_TRUE(interceptions.SetupConfigBuffer(local_buffer.get(),
242 buffer_size));
243
244 // At this point, the interceptions should have been separated into two
245 // groups: one group with the local ("cold") interceptions, and another
246 // group with the interceptions belonging to dlls that will be "hot"
247 // patched on the client. The second group lives on local_buffer, and the
248 // first group remains on the list of interceptions, in this case just one.
249 EXPECT_EQ(1u, interceptions.interceptions_.size());
250
251 int num_dlls, num_functions, num_names;
252 WalkBuffer(local_buffer.get(), buffer_size, &num_dlls, &num_functions,
253 &num_names);
254
255 EXPECT_EQ(3, num_dlls);
256 EXPECT_EQ(4, num_functions);
257 EXPECT_EQ(0, num_names);
258 }
259
260 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/interception_internal.h ('k') | sandbox/win/src/interceptors.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698