security/sandbox/win/src/policy_engine_processor.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #ifndef SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__
michael@0 6 #define SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__
michael@0 7
michael@0 8 #include "base/basictypes.h"
michael@0 9 #include "sandbox/win/src/policy_engine_params.h"
michael@0 10 #include "sandbox/win/src/policy_engine_opcodes.h"
michael@0 11
michael@0 12 namespace sandbox {
michael@0 13
michael@0 14 // This header contains the core policy evaluator. In its simplest form
michael@0 15 // it evaluates a stream of opcodes assuming that they are laid out in
michael@0 16 // memory as opcode groups.
michael@0 17 //
michael@0 18 // An opcode group has N comparison opcodes plus 1 action opcode. For
michael@0 19 // example here we have 3 opcode groups (A, B,C):
michael@0 20 //
michael@0 21 // [comparison 1] <-- group A start
michael@0 22 // [comparison 2]
michael@0 23 // [comparison 3]
michael@0 24 // [action A ]
michael@0 25 // [comparison 1] <-- group B start
michael@0 26 // [action B ]
michael@0 27 // [comparison 1] <-- group C start
michael@0 28 // [comparison 2]
michael@0 29 // [action C ]
michael@0 30 //
michael@0 31 // The opcode evaluator proceeds from the top, evaluating each opcode in
michael@0 32 // sequence. An opcode group is evaluated until the first comparison that
michael@0 33 // returns false. At that point the rest of the group is skipped and evaluation
michael@0 34 // resumes with the first comparison of the next group. When all the comparisons
michael@0 35 // in a group have evaluated to true and the action is reached. The group is
michael@0 36 // considered a matching group.
michael@0 37 //
michael@0 38 // In the 'ShortEval' mode evaluation stops when it reaches the end or the first
michael@0 39 // matching group. The action opcode from this group is the resulting policy
michael@0 40 // action.
michael@0 41 //
michael@0 42 // In the 'RankedEval' mode evaluation stops only when it reaches the end of the
michael@0 43 // the opcode stream. In the process all matching groups are saved and at the
michael@0 44 // end the 'best' group is selected (what makes the best is TBD) and the action
michael@0 45 // from this group is the resulting policy action.
michael@0 46 //
michael@0 47 // As explained above, the policy evaluation of a group is a logical AND of
michael@0 48 // the evaluation of each opcode. However an opcode can request kPolUseOREval
michael@0 49 // which makes the evaluation to use logical OR. Given that each opcode can
michael@0 50 // request its evaluation result to be negated with kPolNegateEval you can
michael@0 51 // achieve the negation of the total group evaluation. This means that if you
michael@0 52 // need to express:
michael@0 53 // if (!(c1 && c2 && c3))
michael@0 54 // You can do it by:
michael@0 55 // if ((!c1) || (!c2) || (!c3))
michael@0 56 //
michael@0 57
michael@0 58 // Possible outcomes of policy evaluation.
michael@0 59 enum PolicyResult {
michael@0 60 NO_POLICY_MATCH,
michael@0 61 POLICY_MATCH,
michael@0 62 POLICY_ERROR
michael@0 63 };
michael@0 64
michael@0 65 // Policy evaluation flags
michael@0 66 // TODO(cpu): implement the options 0 & 4.
michael@0 67 //
michael@0 68 // Stop evaluating as soon as an error is encountered.
michael@0 69 const uint32 kStopOnErrors = 0;
michael@0 70 // Ignore all non fatal opcode evaluation errors.
michael@0 71 const uint32 kIgnoreErrors = 1;
michael@0 72 // Short-circuit evaluation: Only evaluate until opcode group that
michael@0 73 // evaluated to true has been found.
michael@0 74 const uint32 kShortEval = 2;
michael@0 75 // Discussed briefly at the policy design meeting. It will evaluate
michael@0 76 // all rules and then return the 'best' rule that evaluated true.
michael@0 77 const uint32 kRankedEval = 4;
michael@0 78
michael@0 79 // This class evaluates a policy-opcode stream given the memory where the
michael@0 80 // opcodes are and an input 'parameter set'.
michael@0 81 //
michael@0 82 // This class is designed to be callable from interception points
michael@0 83 // as low as the NtXXXX service level (it is not currently safe, but
michael@0 84 // it is designed to be made safe).
michael@0 85 //
michael@0 86 // Its usage in an interception is:
michael@0 87 //
michael@0 88 // POLPARAMS_BEGIN(eval_params)
michael@0 89 // POLPARAM(param1)
michael@0 90 // POLPARAM(param2)
michael@0 91 // POLPARAM(param3)
michael@0 92 // POLPARAM(param4)
michael@0 93 // POLPARAM(param5)
michael@0 94 // POLPARAMS_END;
michael@0 95 //
michael@0 96 // PolicyProcessor pol_evaluator(policy_memory);
michael@0 97 // PolicyResult pr = pol_evaluator.Evaluate(ShortEval, eval_params,
michael@0 98 // _countof(eval_params));
michael@0 99 // if (NO_POLICY_MATCH == pr) {
michael@0 100 // EvalResult policy_action = pol_evaluator.GetAction();
michael@0 101 // // apply policy here...
michael@0 102 // }
michael@0 103 //
michael@0 104 // Where the POLPARAM() arguments are derived from the intercepted function
michael@0 105 // arguments, and represent all the 'interesting' policy inputs, and
michael@0 106 // policy_memory is a memory buffer containing the opcode stream that is the
michael@0 107 // relevant policy for this intercept.
michael@0 108 class PolicyProcessor {
michael@0 109 public:
michael@0 110 // policy_buffer contains opcodes made with OpcodeFactory. They are usually
michael@0 111 // created in the broker process and evaluated in the target process.
michael@0 112
michael@0 113 // This constructor is just a variant of the previous constructor.
michael@0 114 explicit PolicyProcessor(PolicyBuffer* policy)
michael@0 115 : policy_(policy) {
michael@0 116 SetInternalState(0, EVAL_FALSE);
michael@0 117 }
michael@0 118
michael@0 119 // Evaluates a policy-opcode stream. See the comments at the top of this
michael@0 120 // class for more info. Returns POLICY_MATCH if a rule set was found that
michael@0 121 // matches an active policy.
michael@0 122 PolicyResult Evaluate(uint32 options,
michael@0 123 ParameterSet* parameters,
michael@0 124 size_t parameter_count);
michael@0 125
michael@0 126 // If the result of Evaluate() was POLICY_MATCH, calling this function returns
michael@0 127 // the recommended policy action.
michael@0 128 EvalResult GetAction() const;
michael@0 129
michael@0 130 private:
michael@0 131 struct {
michael@0 132 size_t current_index_;
michael@0 133 EvalResult current_result_;
michael@0 134 } state_;
michael@0 135
michael@0 136 // Sets the currently matching action result.
michael@0 137 void SetInternalState(size_t index, EvalResult result);
michael@0 138
michael@0 139 PolicyBuffer* policy_;
michael@0 140 DISALLOW_COPY_AND_ASSIGN(PolicyProcessor);
michael@0 141 };
michael@0 142
michael@0 143 } // namespace sandbox
michael@0 144
michael@0 145 #endif // SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__

mercurial