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