| OLD | NEW |
| (Empty) |
| 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/src/policy_engine_processor.h" | |
| 6 | |
| 7 namespace sandbox { | |
| 8 | |
| 9 void PolicyProcessor::SetInternalState(size_t index, EvalResult result) { | |
| 10 state_.current_index_ = index; | |
| 11 state_.current_result_ = result; | |
| 12 } | |
| 13 | |
| 14 EvalResult PolicyProcessor::GetAction() const { | |
| 15 return state_.current_result_; | |
| 16 } | |
| 17 | |
| 18 // Decides if an opcode can be skipped (not evaluated) or not. The function | |
| 19 // takes as inputs the opcode and the current evaluation context and returns | |
| 20 // true if the opcode should be skipped or not and also can set keep_skipping | |
| 21 // to false to signal that the current instruction should be skipped but not | |
| 22 // the next after the current one. | |
| 23 bool SkipOpcode(PolicyOpcode& opcode, MatchContext* context, | |
| 24 bool* keep_skipping) { | |
| 25 if (opcode.IsAction()) { | |
| 26 uint32 options = context->options; | |
| 27 context->Clear(); | |
| 28 *keep_skipping = false; | |
| 29 return (kPolUseOREval == options)? false : true; | |
| 30 } | |
| 31 *keep_skipping = true; | |
| 32 return true; | |
| 33 } | |
| 34 | |
| 35 PolicyResult PolicyProcessor::Evaluate(uint32 options, | |
| 36 ParameterSet* parameters, | |
| 37 size_t param_count) { | |
| 38 if (NULL == policy_) { | |
| 39 return NO_POLICY_MATCH; | |
| 40 } | |
| 41 if (0 == policy_->opcode_count) { | |
| 42 return NO_POLICY_MATCH; | |
| 43 } | |
| 44 if (!(kShortEval & options)) { | |
| 45 return POLICY_ERROR; | |
| 46 } | |
| 47 | |
| 48 MatchContext context; | |
| 49 bool evaluation = false; | |
| 50 bool skip_group = false; | |
| 51 SetInternalState(0, EVAL_FALSE); | |
| 52 size_t count = policy_->opcode_count; | |
| 53 | |
| 54 // Loop over all the opcodes Evaluating in sequence. Since we only support | |
| 55 // short circuit evaluation, we stop as soon as we find an 'action' opcode | |
| 56 // and the current evaluation is true. | |
| 57 // | |
| 58 // Skipping opcodes can happen when we are in AND mode (!kPolUseOREval) and | |
| 59 // have got EVAL_FALSE or when we are in OR mode (kPolUseOREval) and got | |
| 60 // EVAL_TRUE. Skipping will stop at the next action opcode or at the opcode | |
| 61 // after the action depending on kPolUseOREval. | |
| 62 | |
| 63 for (size_t ix = 0; ix != count; ++ix) { | |
| 64 PolicyOpcode& opcode = policy_->opcodes[ix]; | |
| 65 // Skipping block. | |
| 66 if (skip_group) { | |
| 67 if (SkipOpcode(opcode, &context, &skip_group)) { | |
| 68 continue; | |
| 69 } | |
| 70 } | |
| 71 // Evaluation block. | |
| 72 EvalResult result = opcode.Evaluate(parameters, param_count, &context); | |
| 73 switch (result) { | |
| 74 case EVAL_FALSE: | |
| 75 evaluation = false; | |
| 76 if (kPolUseOREval != context.options) { | |
| 77 skip_group = true; | |
| 78 } | |
| 79 break; | |
| 80 case EVAL_ERROR: | |
| 81 if (kStopOnErrors & options) { | |
| 82 return POLICY_ERROR; | |
| 83 } | |
| 84 break; | |
| 85 case EVAL_TRUE: | |
| 86 evaluation = true; | |
| 87 if (kPolUseOREval == context.options) { | |
| 88 skip_group = true; | |
| 89 } | |
| 90 break; | |
| 91 default: | |
| 92 // We have evaluated an action. | |
| 93 SetInternalState(ix, result); | |
| 94 return POLICY_MATCH; | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 if (evaluation) { | |
| 99 // Reaching the end of the policy with a positive evaluation is probably | |
| 100 // an error: we did not find a final action opcode? | |
| 101 return POLICY_ERROR; | |
| 102 } | |
| 103 return NO_POLICY_MATCH; | |
| 104 } | |
| 105 | |
| 106 | |
| 107 } // namespace sandbox | |
| OLD | NEW |