security/sandbox/win/src/policy_engine_processor.cc

changeset 0
6474c204b198
     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

mercurial