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