1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/policy_engine_processor.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,107 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "sandbox/win/src/policy_engine_processor.h" 1.9 + 1.10 +namespace sandbox { 1.11 + 1.12 +void PolicyProcessor::SetInternalState(size_t index, EvalResult result) { 1.13 + state_.current_index_ = index; 1.14 + state_.current_result_ = result; 1.15 +} 1.16 + 1.17 +EvalResult PolicyProcessor::GetAction() const { 1.18 + return state_.current_result_; 1.19 +} 1.20 + 1.21 +// Decides if an opcode can be skipped (not evaluated) or not. The function 1.22 +// takes as inputs the opcode and the current evaluation context and returns 1.23 +// true if the opcode should be skipped or not and also can set keep_skipping 1.24 +// to false to signal that the current instruction should be skipped but not 1.25 +// the next after the current one. 1.26 +bool SkipOpcode(const PolicyOpcode& opcode, MatchContext* context, 1.27 + bool* keep_skipping) { 1.28 + if (opcode.IsAction()) { 1.29 + uint32 options = context->options; 1.30 + context->Clear(); 1.31 + *keep_skipping = false; 1.32 + return (kPolUseOREval != options); 1.33 + } 1.34 + *keep_skipping = true; 1.35 + return true; 1.36 +} 1.37 + 1.38 +PolicyResult PolicyProcessor::Evaluate(uint32 options, 1.39 + ParameterSet* parameters, 1.40 + size_t param_count) { 1.41 + if (NULL == policy_) { 1.42 + return NO_POLICY_MATCH; 1.43 + } 1.44 + if (0 == policy_->opcode_count) { 1.45 + return NO_POLICY_MATCH; 1.46 + } 1.47 + if (!(kShortEval & options)) { 1.48 + return POLICY_ERROR; 1.49 + } 1.50 + 1.51 + MatchContext context; 1.52 + bool evaluation = false; 1.53 + bool skip_group = false; 1.54 + SetInternalState(0, EVAL_FALSE); 1.55 + size_t count = policy_->opcode_count; 1.56 + 1.57 + // Loop over all the opcodes Evaluating in sequence. Since we only support 1.58 + // short circuit evaluation, we stop as soon as we find an 'action' opcode 1.59 + // and the current evaluation is true. 1.60 + // 1.61 + // Skipping opcodes can happen when we are in AND mode (!kPolUseOREval) and 1.62 + // have got EVAL_FALSE or when we are in OR mode (kPolUseOREval) and got 1.63 + // EVAL_TRUE. Skipping will stop at the next action opcode or at the opcode 1.64 + // after the action depending on kPolUseOREval. 1.65 + 1.66 + for (size_t ix = 0; ix != count; ++ix) { 1.67 + PolicyOpcode& opcode = policy_->opcodes[ix]; 1.68 + // Skipping block. 1.69 + if (skip_group) { 1.70 + if (SkipOpcode(opcode, &context, &skip_group)) { 1.71 + continue; 1.72 + } 1.73 + } 1.74 + // Evaluation block. 1.75 + EvalResult result = opcode.Evaluate(parameters, param_count, &context); 1.76 + switch (result) { 1.77 + case EVAL_FALSE: 1.78 + evaluation = false; 1.79 + if (kPolUseOREval != context.options) { 1.80 + skip_group = true; 1.81 + } 1.82 + break; 1.83 + case EVAL_ERROR: 1.84 + if (kStopOnErrors & options) { 1.85 + return POLICY_ERROR; 1.86 + } 1.87 + break; 1.88 + case EVAL_TRUE: 1.89 + evaluation = true; 1.90 + if (kPolUseOREval == context.options) { 1.91 + skip_group = true; 1.92 + } 1.93 + break; 1.94 + default: 1.95 + // We have evaluated an action. 1.96 + SetInternalState(ix, result); 1.97 + return POLICY_MATCH; 1.98 + } 1.99 + } 1.100 + 1.101 + if (evaluation) { 1.102 + // Reaching the end of the policy with a positive evaluation is probably 1.103 + // an error: we did not find a final action opcode? 1.104 + return POLICY_ERROR; 1.105 + } 1.106 + return NO_POLICY_MATCH; 1.107 +} 1.108 + 1.109 + 1.110 +} // namespace sandbox