| 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 |