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