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

Side by Side Diff: sandbox/win/src/policy_opcodes_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/policy_low_level_unittest.cc ('k') | sandbox/win/src/policy_params.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) 2006-2008 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 <stddef.h>
6 #include <stdint.h>
7
8 #include "sandbox/win/src/policy_engine_opcodes.h"
9 #include "sandbox/win/src/policy_engine_params.h"
10 #include "sandbox/win/src/sandbox_nt_types.h"
11 #include "sandbox/win/src/sandbox_types.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14
15 #define INIT_GLOBAL_RTL(member) \
16 g_nt.member = reinterpret_cast<member##Function>( \
17 ::GetProcAddress(ntdll, #member)); \
18 if (NULL == g_nt.member) \
19 return false
20
21 namespace sandbox {
22
23 const size_t kOpcodeMemory = 1024;
24
25 SANDBOX_INTERCEPT NtExports g_nt;
26
27 bool SetupNtdllImports() {
28 HMODULE ntdll = ::GetModuleHandle(kNtdllName);
29
30 INIT_GLOBAL_RTL(RtlAllocateHeap);
31 INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString);
32 INIT_GLOBAL_RTL(RtlCompareUnicodeString);
33 INIT_GLOBAL_RTL(RtlCreateHeap);
34 INIT_GLOBAL_RTL(RtlDestroyHeap);
35 INIT_GLOBAL_RTL(RtlFreeHeap);
36 INIT_GLOBAL_RTL(_strnicmp);
37 INIT_GLOBAL_RTL(strlen);
38 INIT_GLOBAL_RTL(wcslen);
39
40 return true;
41 }
42
43 TEST(PolicyEngineTest, ParameterSetTest) {
44 void* pv1 = reinterpret_cast<void*>(0x477EAA5);
45 const void* pv2 = reinterpret_cast<void*>(0x987654);
46 ParameterSet pset1 = ParamPickerMake(pv1);
47 ParameterSet pset2 = ParamPickerMake(pv2);
48
49 // Test that we can store and retrieve a void pointer:
50 const void* result1 =0;
51 uint32_t result2 = 0;
52 EXPECT_TRUE(pset1.Get(&result1));
53 EXPECT_TRUE(pv1 == result1);
54 EXPECT_FALSE(pset1.Get(&result2));
55 EXPECT_TRUE(pset2.Get(&result1));
56 EXPECT_TRUE(pv2 == result1);
57 EXPECT_FALSE(pset2.Get(&result2));
58
59 // Test that we can store and retrieve a uint32_t:
60 uint32_t number = 12747;
61 ParameterSet pset3 = ParamPickerMake(number);
62 EXPECT_FALSE(pset3.Get(&result1));
63 EXPECT_TRUE(pset3.Get(&result2));
64 EXPECT_EQ(number, result2);
65
66 // Test that we can store and retrieve a string:
67 const wchar_t* txt = L"S231L";
68 ParameterSet pset4 = ParamPickerMake(txt);
69 const wchar_t* result3 = NULL;
70 EXPECT_TRUE(pset4.Get(&result3));
71 EXPECT_EQ(0, wcscmp(txt, result3));
72 }
73
74 TEST(PolicyEngineTest, OpcodeConstraints) {
75 // Test that PolicyOpcode has no virtual functions
76 // because these objects are copied over to other processes
77 // so they cannot have vtables.
78 EXPECT_FALSE(__is_polymorphic(PolicyOpcode));
79 // Keep developers from adding smarts to the opcodes which should
80 // be pretty much a bag of bytes with a OO interface.
81 EXPECT_TRUE(__has_trivial_destructor(PolicyOpcode));
82 EXPECT_TRUE(__has_trivial_constructor(PolicyOpcode));
83 EXPECT_TRUE(__has_trivial_copy(PolicyOpcode));
84 }
85
86 TEST(PolicyEngineTest, TrueFalseOpcodes) {
87 void* dummy = NULL;
88 ParameterSet ppb1 = ParamPickerMake(dummy);
89 char memory[kOpcodeMemory];
90 OpcodeFactory opcode_maker(memory, sizeof(memory));
91
92 // This opcode always evaluates to true.
93 PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone);
94 ASSERT_NE(nullptr, op1);
95 EXPECT_EQ(EVAL_FALSE, op1->Evaluate(&ppb1, 1, NULL));
96 EXPECT_FALSE(op1->IsAction());
97
98 // This opcode always evaluates to false.
99 PolicyOpcode* op2 = opcode_maker.MakeOpAlwaysTrue(kPolNone);
100 ASSERT_NE(nullptr, op2);
101 EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL));
102
103 // Nulls not allowed on the params.
104 EXPECT_EQ(EVAL_ERROR, op2->Evaluate(NULL, 0, NULL));
105 EXPECT_EQ(EVAL_ERROR, op2->Evaluate(NULL, 1, NULL));
106
107 // True and False opcodes do not 'require' a number of parameters
108 EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 0, NULL));
109 EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL));
110
111 // Test Inverting the logic. Note that inversion is done outside
112 // any particular opcode evaluation so no need to repeat for all
113 // opcodes.
114 PolicyOpcode* op3 = opcode_maker.MakeOpAlwaysFalse(kPolNegateEval);
115 ASSERT_NE(nullptr, op3);
116 EXPECT_EQ(EVAL_TRUE, op3->Evaluate(&ppb1, 1, NULL));
117 PolicyOpcode* op4 = opcode_maker.MakeOpAlwaysTrue(kPolNegateEval);
118 ASSERT_NE(nullptr, op4);
119 EXPECT_EQ(EVAL_FALSE, op4->Evaluate(&ppb1, 1, NULL));
120
121 // Test that we clear the match context
122 PolicyOpcode* op5 = opcode_maker.MakeOpAlwaysTrue(kPolClearContext);
123 ASSERT_NE(nullptr, op5);
124 MatchContext context;
125 context.position = 1;
126 context.options = kPolUseOREval;
127 EXPECT_EQ(EVAL_TRUE, op5->Evaluate(&ppb1, 1, &context));
128 EXPECT_EQ(0u, context.position);
129 MatchContext context2;
130 EXPECT_EQ(context2.options, context.options);
131 }
132
133 TEST(PolicyEngineTest, OpcodeMakerCase1) {
134 // Testing that the opcode maker does not overrun the
135 // supplied buffer. It should only be able to make 'count' opcodes.
136 void* dummy = NULL;
137 ParameterSet ppb1 = ParamPickerMake(dummy);
138
139 char memory[kOpcodeMemory];
140 OpcodeFactory opcode_maker(memory, sizeof(memory));
141 size_t count = sizeof(memory) / sizeof(PolicyOpcode);
142
143 for (size_t ix =0; ix != count; ++ix) {
144 PolicyOpcode* op = opcode_maker.MakeOpAlwaysFalse(kPolNone);
145 ASSERT_NE(nullptr, op);
146 EXPECT_EQ(EVAL_FALSE, op->Evaluate(&ppb1, 1, NULL));
147 }
148 // There should be no room more another opcode:
149 PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone);
150 ASSERT_EQ(nullptr, op1);
151 }
152
153 TEST(PolicyEngineTest, OpcodeMakerCase2) {
154 SetupNtdllImports();
155 // Testing that the opcode maker does not overrun the
156 // supplied buffer. It should only be able to make 'count' opcodes.
157 // The difference with the previous test is that this opcodes allocate
158 // the string 'txt2' inside the same buffer.
159 const wchar_t* txt1 = L"1234";
160 const wchar_t txt2[] = L"123";
161
162 ParameterSet ppb1 = ParamPickerMake(txt1);
163 MatchContext mc1;
164
165 char memory[kOpcodeMemory];
166 OpcodeFactory opcode_maker(memory, sizeof(memory));
167 size_t count = sizeof(memory) / (sizeof(PolicyOpcode) + sizeof(txt2));
168
169 // Test that it does not overrun the buffer.
170 for (size_t ix =0; ix != count; ++ix) {
171 PolicyOpcode* op = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
172 CASE_SENSITIVE,
173 kPolClearContext);
174 ASSERT_NE(nullptr, op);
175 EXPECT_EQ(EVAL_TRUE, op->Evaluate(&ppb1, 1, &mc1));
176 }
177
178 // There should be no room more another opcode:
179 PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
180 CASE_SENSITIVE,
181 kPolNone);
182 ASSERT_EQ(nullptr, op1);
183 }
184
185 TEST(PolicyEngineTest, IntegerOpcodes) {
186 const wchar_t* txt = L"abcdef";
187 uint32_t num1 = 42;
188 uint32_t num2 = 113377;
189
190 ParameterSet pp_wrong1 = ParamPickerMake(txt);
191 ParameterSet pp_num1 = ParamPickerMake(num1);
192 ParameterSet pp_num2 = ParamPickerMake(num2);
193
194 char memory[kOpcodeMemory];
195 OpcodeFactory opcode_maker(memory, sizeof(memory));
196
197 // Test basic match for uint32s 42 == 42 and 42 != 113377.
198 PolicyOpcode* op_m42 = opcode_maker.MakeOpNumberMatch(0, 42UL, kPolNone);
199 ASSERT_NE(nullptr, op_m42);
200 EXPECT_EQ(EVAL_TRUE, op_m42->Evaluate(&pp_num1, 1, NULL));
201 EXPECT_EQ(EVAL_FALSE, op_m42->Evaluate(&pp_num2, 1, NULL));
202 EXPECT_EQ(EVAL_ERROR, op_m42->Evaluate(&pp_wrong1, 1, NULL));
203
204 // Test basic match for void pointers.
205 const void* vp = NULL;
206 ParameterSet pp_num3 = ParamPickerMake(vp);
207 PolicyOpcode* op_vp_null = opcode_maker.MakeOpVoidPtrMatch(0, NULL,
208 kPolNone);
209 ASSERT_NE(nullptr, op_vp_null);
210 EXPECT_EQ(EVAL_TRUE, op_vp_null->Evaluate(&pp_num3, 1, NULL));
211 EXPECT_EQ(EVAL_FALSE, op_vp_null->Evaluate(&pp_num1, 1, NULL));
212 EXPECT_EQ(EVAL_ERROR, op_vp_null->Evaluate(&pp_wrong1, 1, NULL));
213
214 // Basic range test [41 43] (inclusive).
215 PolicyOpcode* op_range1 =
216 opcode_maker.MakeOpNumberMatchRange(0, 41, 43, kPolNone);
217 ASSERT_NE(nullptr, op_range1);
218 EXPECT_EQ(EVAL_TRUE, op_range1->Evaluate(&pp_num1, 1, NULL));
219 EXPECT_EQ(EVAL_FALSE, op_range1->Evaluate(&pp_num2, 1, NULL));
220 EXPECT_EQ(EVAL_ERROR, op_range1->Evaluate(&pp_wrong1, 1, NULL));
221 }
222
223 TEST(PolicyEngineTest, LogicalOpcodes) {
224 char memory[kOpcodeMemory];
225 OpcodeFactory opcode_maker(memory, sizeof(memory));
226
227 uint32_t num1 = 0x10100702;
228 ParameterSet pp_num1 = ParamPickerMake(num1);
229
230 PolicyOpcode* op_and1 =
231 opcode_maker.MakeOpNumberAndMatch(0, 0x00100000, kPolNone);
232 ASSERT_NE(nullptr, op_and1);
233 EXPECT_EQ(EVAL_TRUE, op_and1->Evaluate(&pp_num1, 1, NULL));
234 PolicyOpcode* op_and2 =
235 opcode_maker.MakeOpNumberAndMatch(0, 0x00000001, kPolNone);
236 ASSERT_NE(nullptr, op_and2);
237 EXPECT_EQ(EVAL_FALSE, op_and2->Evaluate(&pp_num1, 1, NULL));
238 }
239
240 TEST(PolicyEngineTest, WCharOpcodes1) {
241 SetupNtdllImports();
242
243 const wchar_t* txt1 = L"the quick fox jumps over the lazy dog";
244 const wchar_t txt2[] = L"the quick";
245 const wchar_t txt3[] = L" fox jumps";
246 const wchar_t txt4[] = L"the lazy dog";
247 const wchar_t txt5[] = L"jumps over";
248 const wchar_t txt6[] = L"g";
249
250 ParameterSet pp_tc1 = ParamPickerMake(txt1);
251 char memory[kOpcodeMemory];
252 OpcodeFactory opcode_maker(memory, sizeof(memory));
253
254 PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
255 CASE_SENSITIVE,
256 kPolNone);
257 ASSERT_NE(nullptr, op1);
258
259 // Simplest substring match from pos 0. It should be a successful match
260 // and the match context should be updated.
261 MatchContext mc1;
262 EXPECT_EQ(EVAL_TRUE, op1->Evaluate(&pp_tc1, 1, &mc1));
263 EXPECT_TRUE(_countof(txt2) == mc1.position + 1);
264
265 // Matching again should fail and the context should be unmodified.
266 EXPECT_EQ(EVAL_FALSE, op1->Evaluate(&pp_tc1, 1, &mc1));
267 EXPECT_TRUE(_countof(txt2) == mc1.position + 1);
268
269 // Using the same match context we should continue where we left
270 // in the previous successful match,
271 PolicyOpcode* op3 = opcode_maker.MakeOpWStringMatch(0, txt3, 0,
272 CASE_SENSITIVE,
273 kPolNone);
274 ASSERT_NE(nullptr, op3);
275 EXPECT_EQ(EVAL_TRUE, op3->Evaluate(&pp_tc1, 1, &mc1));
276 EXPECT_TRUE(_countof(txt3) + _countof(txt2) == mc1.position + 2);
277
278 // We now keep on matching but now we skip 6 characters which means
279 // we skip the string ' over '. And we zero the match context. This is
280 // the primitive that we use to build '??'.
281 PolicyOpcode* op4 = opcode_maker.MakeOpWStringMatch(0, txt4, 6,
282 CASE_SENSITIVE,
283 kPolClearContext);
284 ASSERT_NE(nullptr, op4);
285 EXPECT_EQ(EVAL_TRUE, op4->Evaluate(&pp_tc1, 1, &mc1));
286 EXPECT_EQ(0u, mc1.position);
287
288 // Test that we can properly match the last part of the string
289 PolicyOpcode* op4b = opcode_maker.MakeOpWStringMatch(0, txt4, kSeekToEnd,
290 CASE_SENSITIVE,
291 kPolClearContext);
292 ASSERT_NE(nullptr, op4b);
293 EXPECT_EQ(EVAL_TRUE, op4b->Evaluate(&pp_tc1, 1, &mc1));
294 EXPECT_EQ(0u, mc1.position);
295
296 // Test matching 'jumps over' over the entire string. This is the
297 // primitive we build '*' from.
298 PolicyOpcode* op5 = opcode_maker.MakeOpWStringMatch(0, txt5, kSeekForward,
299 CASE_SENSITIVE, kPolNone);
300 ASSERT_NE(nullptr, op5);
301 EXPECT_EQ(EVAL_TRUE, op5->Evaluate(&pp_tc1, 1, &mc1));
302 EXPECT_EQ(24u, mc1.position);
303
304 // Test that we don't match because it is not at the end of the string
305 PolicyOpcode* op5b = opcode_maker.MakeOpWStringMatch(0, txt5, kSeekToEnd,
306 CASE_SENSITIVE,
307 kPolNone);
308 ASSERT_NE(nullptr, op5b);
309 EXPECT_EQ(EVAL_FALSE, op5b->Evaluate(&pp_tc1, 1, &mc1));
310 EXPECT_EQ(24u, mc1.position);
311
312 // Test that we function if the string does not fit. In this case we
313 // try to match 'the lazy dog' against 'he lazy dog'.
314 PolicyOpcode* op6 = opcode_maker.MakeOpWStringMatch(0, txt4, 2,
315 CASE_SENSITIVE, kPolNone);
316 ASSERT_NE(nullptr, op6);
317 EXPECT_EQ(EVAL_FALSE, op6->Evaluate(&pp_tc1, 1, &mc1));
318
319 // Testing matching against 'g' which should be the last char.
320 MatchContext mc2;
321 PolicyOpcode* op7 = opcode_maker.MakeOpWStringMatch(0, txt6, kSeekForward,
322 CASE_SENSITIVE, kPolNone);
323 ASSERT_NE(nullptr, op7);
324 EXPECT_EQ(EVAL_TRUE, op7->Evaluate(&pp_tc1, 1, &mc2));
325 EXPECT_EQ(37u, mc2.position);
326
327 // Trying to match again should fail since we are in the last char.
328 // This also covers a couple of boundary conditions.
329 EXPECT_EQ(EVAL_FALSE, op7->Evaluate(&pp_tc1, 1, &mc2));
330 EXPECT_EQ(37u, mc2.position);
331 }
332
333 TEST(PolicyEngineTest, WCharOpcodes2) {
334 SetupNtdllImports();
335
336 const wchar_t* path1 = L"c:\\documents and settings\\Microsoft\\BLAH.txt";
337 const wchar_t txt1[] = L"Settings\\microsoft";
338 ParameterSet pp_tc1 = ParamPickerMake(path1);
339
340 char memory[kOpcodeMemory];
341 OpcodeFactory opcode_maker(memory, sizeof(memory));
342 MatchContext mc1;
343
344 // Testing case-insensitive does not buy us much since it this option
345 // is just passed to the Microsoft API that we use normally, but just for
346 // coverage, here it is:
347 PolicyOpcode* op1s = opcode_maker.MakeOpWStringMatch(0, txt1, kSeekForward,
348 CASE_SENSITIVE, kPolNone);
349 ASSERT_NE(nullptr, op1s);
350 PolicyOpcode* op1i = opcode_maker.MakeOpWStringMatch(0, txt1, kSeekForward,
351 CASE_INSENSITIVE,
352 kPolNone);
353 ASSERT_NE(nullptr, op1i);
354 EXPECT_EQ(EVAL_FALSE, op1s->Evaluate(&pp_tc1, 1, &mc1));
355 EXPECT_EQ(EVAL_TRUE, op1i->Evaluate(&pp_tc1, 1, &mc1));
356 EXPECT_EQ(35u, mc1.position);
357 }
358
359 TEST(PolicyEngineTest, ActionOpcodes) {
360 char memory[kOpcodeMemory];
361 OpcodeFactory opcode_maker(memory, sizeof(memory));
362 MatchContext mc1;
363 void* dummy = NULL;
364 ParameterSet ppb1 = ParamPickerMake(dummy);
365
366 PolicyOpcode* op1 = opcode_maker.MakeOpAction(ASK_BROKER, kPolNone);
367 ASSERT_NE(nullptr, op1);
368 EXPECT_TRUE(op1->IsAction());
369 EXPECT_EQ(ASK_BROKER, op1->Evaluate(&ppb1, 1, &mc1));
370 }
371
372 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/policy_low_level_unittest.cc ('k') | sandbox/win/src/policy_params.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698