Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / sandbox / win / src / policy_opcodes_unittest.cc
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 "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"
10
11
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
17
18 namespace sandbox {
19
20 SANDBOX_INTERCEPT NtExports g_nt;
21
22 bool SetupNtdllImports() {
23     HMODULE ntdll = ::GetModuleHandle(kNtdllName);
24
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);
34
35   return true;
36 }
37
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);
43
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));
53
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);
60
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));
67 }
68
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));
79 }
80
81 TEST(PolicyEngineTest, TrueFalseOpcodes) {
82   void* dummy = NULL;
83   ParameterSet ppb1 = ParamPickerMake(dummy);
84   char memory[1024];
85   OpcodeFactory opcode_maker(memory, sizeof(memory));
86
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());
91
92   // This opcode always evaluates to false.
93   PolicyOpcode* op2 = opcode_maker.MakeOpAlwaysTrue(kPolNone);
94   EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL));
95
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));
99
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));
103
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));
111
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);
121 }
122
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);
128
129   char memory[256];
130   OpcodeFactory opcode_maker(memory, sizeof(memory));
131   size_t count = sizeof(memory) / sizeof(PolicyOpcode);
132
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));
137   }
138   // There should be no room more another opcode:
139   PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone);
140   ASSERT_TRUE(NULL == op1);
141 }
142
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";
151
152   ParameterSet ppb1 = ParamPickerMake(txt1);
153   MatchContext mc1;
154
155   char memory[256];
156   OpcodeFactory opcode_maker(memory, sizeof(memory));
157   size_t count = sizeof(memory) / (sizeof(PolicyOpcode) + sizeof(txt2));
158
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));
166   }
167
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);
173 }
174
175 TEST(PolicyEngineTest, IntegerOpcodes) {
176   const wchar_t* txt = L"abcdef";
177   unsigned long num1 = 42;
178   unsigned long num2 = 113377;
179
180   ParameterSet pp_wrong1 = ParamPickerMake(txt);
181   ParameterSet pp_num1 = ParamPickerMake(num1);
182   ParameterSet pp_num2 = ParamPickerMake(num2);
183
184   char memory[128];
185   OpcodeFactory opcode_maker(memory, sizeof(memory));
186
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));
192
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));
201
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));
208 }
209
210 TEST(PolicyEngineTest, LogicalOpcodes) {
211   char memory[128];
212   OpcodeFactory opcode_maker(memory, sizeof(memory));
213
214   unsigned long num1 = 0x10100702;
215   ParameterSet pp_num1 = ParamPickerMake(num1);
216
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));
223 }
224
225 TEST(PolicyEngineTest, WCharOpcodes1) {
226   SetupNtdllImports();
227
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";
234
235   ParameterSet pp_tc1 = ParamPickerMake(txt1);
236   char memory[512];
237   OpcodeFactory opcode_maker(memory, sizeof(memory));
238
239   PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0,
240                                                       CASE_SENSITIVE,
241                                                       kPolNone);
242
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);
248
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);
252
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);
260
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);
269
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);
276
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);
283
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));
289
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);
295
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));
301
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));
305 }
306
307 TEST(PolicyEngineTest, WCharOpcodes2) {
308   SetupNtdllImports();
309
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);
313
314   char memory[256];
315   OpcodeFactory opcode_maker(memory, sizeof(memory));
316   MatchContext mc1;
317
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);
329 }
330
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);
337
338   PolicyOpcode* op1 = opcode_maker.MakeOpAction(ASK_BROKER, kPolNone);
339   EXPECT_TRUE(op1->IsAction());
340   EXPECT_EQ(ASK_BROKER, op1->Evaluate(&ppb1, 1, &mc1));
341 }
342
343 }  // namespace sandbox