OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 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 "sandbox/win/src/policy_low_level.h" | 5 #include "sandbox/win/src/policy_low_level.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <string> |
8 #include <stdint.h> | 8 #include <map> |
9 | 9 |
10 #include <map> | 10 #include "base/basictypes.h" |
11 #include <string> | |
12 | 11 |
13 namespace { | 12 namespace { |
14 | 13 |
15 // A single rule can use at most this amount of memory. | 14 // A single rule can use at most this amount of memory. |
16 const size_t kRuleBufferSize = 1024*4; | 15 const size_t kRuleBufferSize = 1024*4; |
17 | 16 |
18 // The possible states of the string matching opcode generator. | 17 // The possible states of the string matching opcode generator. |
19 enum { | 18 enum { |
20 PENDING_NONE, | 19 PENDING_NONE, |
21 PENDING_ASTERISK, // Have seen an '*' but have not generated an opcode. | 20 PENDING_ASTERISK, // Have seen an '*' but have not generated an opcode. |
22 PENDING_QMARK, // Have seen an '?' but have not generated an opcode. | 21 PENDING_QMARK, // Have seen an '?' but have not generated an opcode. |
23 }; | 22 }; |
24 | 23 |
25 // The category of the last character seen by the string matching opcode | 24 // The category of the last character seen by the string matching opcode |
26 // generator. | 25 // generator. |
27 const uint32_t kLastCharIsNone = 0; | 26 const uint32 kLastCharIsNone = 0; |
28 const uint32_t kLastCharIsAlpha = 1; | 27 const uint32 kLastCharIsAlpha = 1; |
29 const uint32_t kLastCharIsWild = 2; | 28 const uint32 kLastCharIsWild = 2; |
30 const uint32_t kLastCharIsAsterisk = kLastCharIsWild + 4; | 29 const uint32 kLastCharIsAsterisk = kLastCharIsWild + 4; |
31 const uint32_t kLastCharIsQuestionM = kLastCharIsWild + 8; | 30 const uint32 kLastCharIsQuestionM = kLastCharIsWild + 8; |
32 } | 31 } |
33 | 32 |
34 namespace sandbox { | 33 namespace sandbox { |
35 | 34 |
36 LowLevelPolicy::LowLevelPolicy(PolicyGlobal* policy_store) | 35 LowLevelPolicy::LowLevelPolicy(PolicyGlobal* policy_store) |
37 : policy_store_(policy_store) { | 36 : policy_store_(policy_store) { |
38 } | 37 } |
39 | 38 |
40 // Adding a rule is nothing more than pushing it into an stl container. Done() | 39 // Adding a rule is nothing more than pushing it into an stl container. Done() |
41 // is called for the rule in case the code that made the rule in the first | 40 // is called for the rule in case the code that made the rule in the first |
(...skipping 20 matching lines...) Expand all Loading... |
62 // Here is where the heavy byte shuffling is done. We take all the rules and | 61 // Here is where the heavy byte shuffling is done. We take all the rules and |
63 // 'compile' them into a single memory region. Now, the rules are in random | 62 // 'compile' them into a single memory region. Now, the rules are in random |
64 // order so the first step is to reorganize them into a stl map that is keyed | 63 // order so the first step is to reorganize them into a stl map that is keyed |
65 // by the service id and as a value contains a list with all the rules that | 64 // by the service id and as a value contains a list with all the rules that |
66 // belong to that service. Then we enter the big for-loop where we carve a | 65 // belong to that service. Then we enter the big for-loop where we carve a |
67 // memory zone for the opcodes and the data and call RebindCopy on each rule | 66 // memory zone for the opcodes and the data and call RebindCopy on each rule |
68 // so they all end up nicely packed in the policy_store_. | 67 // so they all end up nicely packed in the policy_store_. |
69 bool LowLevelPolicy::Done() { | 68 bool LowLevelPolicy::Done() { |
70 typedef std::list<RuleNode> RuleNodes; | 69 typedef std::list<RuleNode> RuleNodes; |
71 typedef std::list<const PolicyRule*> RuleList; | 70 typedef std::list<const PolicyRule*> RuleList; |
72 typedef std::map<uint32_t, RuleList> Mmap; | 71 typedef std::map<uint32, RuleList> Mmap; |
73 Mmap mmap; | 72 Mmap mmap; |
74 | 73 |
75 for (RuleNodes::iterator it = rules_.begin(); it != rules_.end(); ++it) { | 74 for (RuleNodes::iterator it = rules_.begin(); it != rules_.end(); ++it) { |
76 mmap[it->service].push_back(it->rule); | 75 mmap[it->service].push_back(it->rule); |
77 } | 76 } |
78 | 77 |
79 PolicyBuffer* current_buffer = &policy_store_->data[0]; | 78 PolicyBuffer* current_buffer = &policy_store_->data[0]; |
80 char* buffer_end = reinterpret_cast<char*>(current_buffer) + | 79 char* buffer_end = reinterpret_cast<char*>(current_buffer) + |
81 policy_store_->data_size; | 80 policy_store_->data_size; |
82 size_t avail_size = policy_store_->data_size; | 81 size_t avail_size = policy_store_->data_size; |
83 | 82 |
84 for (Mmap::iterator it = mmap.begin(); it != mmap.end(); ++it) { | 83 for (Mmap::iterator it = mmap.begin(); it != mmap.end(); ++it) { |
85 uint32_t service = (*it).first; | 84 uint32 service = (*it).first; |
86 if (service >= kMaxServiceCount) { | 85 if (service >= kMaxServiceCount) { |
87 return false; | 86 return false; |
88 } | 87 } |
89 policy_store_->entry[service] = current_buffer; | 88 policy_store_->entry[service] = current_buffer; |
90 | 89 |
91 RuleList::iterator rules_it = (*it).second.begin(); | 90 RuleList::iterator rules_it = (*it).second.begin(); |
92 RuleList::iterator rules_it_end = (*it).second.end(); | 91 RuleList::iterator rules_it_end = (*it).second.end(); |
93 | 92 |
94 size_t svc_opcode_count = 0; | 93 size_t svc_opcode_count = 0; |
95 | 94 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 | 148 |
150 // This function get called from a simple state machine implemented in | 149 // This function get called from a simple state machine implemented in |
151 // AddStringMatch() which passes the current state (in state) and it passes | 150 // AddStringMatch() which passes the current state (in state) and it passes |
152 // true in last_call if AddStringMatch() has finished processing the input | 151 // true in last_call if AddStringMatch() has finished processing the input |
153 // pattern string and this would be the last call to generate any pending | 152 // pattern string and this would be the last call to generate any pending |
154 // opcode. The skip_count is the currently accumulated number of '?' seen so | 153 // opcode. The skip_count is the currently accumulated number of '?' seen so |
155 // far and once the associated opcode is generated this function sets it back | 154 // far and once the associated opcode is generated this function sets it back |
156 // to zero. | 155 // to zero. |
157 bool PolicyRule::GenStringOpcode(RuleType rule_type, | 156 bool PolicyRule::GenStringOpcode(RuleType rule_type, |
158 StringMatchOptions match_opts, | 157 StringMatchOptions match_opts, |
159 uint16_t parameter, | 158 uint16 parameter, int state, bool last_call, |
160 int state, | 159 int* skip_count, base::string16* fragment) { |
161 bool last_call, | 160 |
162 int* skip_count, | |
163 base::string16* fragment) { | |
164 // The last opcode must: | 161 // The last opcode must: |
165 // 1) Always clear the context. | 162 // 1) Always clear the context. |
166 // 2) Preserve the negation. | 163 // 2) Preserve the negation. |
167 // 3) Remove the 'OR' mode flag. | 164 // 3) Remove the 'OR' mode flag. |
168 uint32_t options = kPolNone; | 165 uint32 options = kPolNone; |
169 if (last_call) { | 166 if (last_call) { |
170 if (IF_NOT == rule_type) { | 167 if (IF_NOT == rule_type) { |
171 options = kPolClearContext | kPolNegateEval; | 168 options = kPolClearContext | kPolNegateEval; |
172 } else { | 169 } else { |
173 options = kPolClearContext; | 170 options = kPolClearContext; |
174 } | 171 } |
175 } else if (IF_NOT == rule_type) { | 172 } else if (IF_NOT == rule_type) { |
176 options = kPolUseOREval | kPolNegateEval; | 173 options = kPolUseOREval | kPolNegateEval; |
177 } | 174 } |
178 | 175 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 match_opts, options); | 212 match_opts, options); |
216 } | 213 } |
217 if (NULL == op) { | 214 if (NULL == op) { |
218 return false; | 215 return false; |
219 } | 216 } |
220 ++buffer_->opcode_count; | 217 ++buffer_->opcode_count; |
221 fragment->clear(); | 218 fragment->clear(); |
222 return true; | 219 return true; |
223 } | 220 } |
224 | 221 |
225 bool PolicyRule::AddStringMatch(RuleType rule_type, | 222 bool PolicyRule::AddStringMatch(RuleType rule_type, int16 parameter, |
226 int16_t parameter, | |
227 const wchar_t* string, | 223 const wchar_t* string, |
228 StringMatchOptions match_opts) { | 224 StringMatchOptions match_opts) { |
229 if (done_) { | 225 if (done_) { |
230 // Do not allow to add more rules after generating the action opcode. | 226 // Do not allow to add more rules after generating the action opcode. |
231 return false; | 227 return false; |
232 } | 228 } |
233 | 229 |
234 const wchar_t* current_char = string; | 230 const wchar_t* current_char = string; |
235 uint32_t last_char = kLastCharIsNone; | 231 uint32 last_char = kLastCharIsNone; |
236 int state = PENDING_NONE; | 232 int state = PENDING_NONE; |
237 int skip_count = 0; // counts how many '?' we have seen in a row. | 233 int skip_count = 0; // counts how many '?' we have seen in a row. |
238 base::string16 fragment; // accumulates the non-wildcard part. | 234 base::string16 fragment; // accumulates the non-wildcard part. |
239 | 235 |
240 while (L'\0' != *current_char) { | 236 while (L'\0' != *current_char) { |
241 switch (*current_char) { | 237 switch (*current_char) { |
242 case L'*': | 238 case L'*': |
243 if (kLastCharIsWild & last_char) { | 239 if (kLastCharIsWild & last_char) { |
244 // '**' and '&*' is an error. | 240 // '**' and '&*' is an error. |
245 return false; | 241 return false; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 } | 273 } |
278 | 274 |
279 if (!GenStringOpcode(rule_type, match_opts, parameter, | 275 if (!GenStringOpcode(rule_type, match_opts, parameter, |
280 state, true, &skip_count, &fragment)) { | 276 state, true, &skip_count, &fragment)) { |
281 return false; | 277 return false; |
282 } | 278 } |
283 return true; | 279 return true; |
284 } | 280 } |
285 | 281 |
286 bool PolicyRule::AddNumberMatch(RuleType rule_type, | 282 bool PolicyRule::AddNumberMatch(RuleType rule_type, |
287 int16_t parameter, | 283 int16 parameter, |
288 uint32_t number, | 284 uint32 number, |
289 RuleOp comparison_op) { | 285 RuleOp comparison_op) { |
290 if (done_) { | 286 if (done_) { |
291 // Do not allow to add more rules after generating the action opcode. | 287 // Do not allow to add more rules after generating the action opcode. |
292 return false; | 288 return false; |
293 } | 289 } |
294 uint32_t opts = (rule_type == IF_NOT) ? kPolNegateEval : kPolNone; | 290 uint32 opts = (rule_type == IF_NOT)? kPolNegateEval : kPolNone; |
295 | 291 |
296 if (EQUAL == comparison_op) { | 292 if (EQUAL == comparison_op) { |
297 if (NULL == opcode_factory_->MakeOpNumberMatch(parameter, number, opts)) { | 293 if (NULL == opcode_factory_->MakeOpNumberMatch(parameter, number, opts)) { |
298 return false; | 294 return false; |
299 } | 295 } |
300 } else if (AND == comparison_op) { | 296 } else if (AND == comparison_op) { |
301 if (NULL == opcode_factory_->MakeOpNumberAndMatch(parameter, number, | 297 if (NULL == opcode_factory_->MakeOpNumberAndMatch(parameter, number, |
302 opts)) { | 298 opts)) { |
303 return false; | 299 return false; |
304 } | 300 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 | 347 |
352 return true; | 348 return true; |
353 } | 349 } |
354 | 350 |
355 PolicyRule::~PolicyRule() { | 351 PolicyRule::~PolicyRule() { |
356 delete [] reinterpret_cast<char*>(buffer_); | 352 delete [] reinterpret_cast<char*>(buffer_); |
357 delete opcode_factory_; | 353 delete opcode_factory_; |
358 } | 354 } |
359 | 355 |
360 } // namespace sandbox | 356 } // namespace sandbox |
OLD | NEW |