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