diff options
Diffstat (limited to 'sandbox/src/policy_engine_processor.h')
-rw-r--r-- | sandbox/src/policy_engine_processor.h | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/sandbox/src/policy_engine_processor.h b/sandbox/src/policy_engine_processor.h new file mode 100644 index 0000000..9adb49b --- /dev/null +++ b/sandbox/src/policy_engine_processor.h @@ -0,0 +1,170 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__ +#define SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__ + +#include "base/basictypes.h" +#include "sandbox/src/policy_engine_params.h" +#include "sandbox/src/policy_engine_opcodes.h" + +namespace sandbox { + +// This header contains the core policy evaluator. In its simplest form +// it evaluates a stream of opcodes assuming that they are laid out in +// memory as opcode groups. +// +// An opcode group has N comparison opcodes plus 1 action opcode. For +// example here we have 3 opcode groups (A, B,C): +// +// [comparison 1] <-- group A start +// [comparison 2] +// [comparison 3] +// [action A ] +// [comparison 1] <-- group B start +// [action B ] +// [comparison 1] <-- group C start +// [comparison 2] +// [action C ] +// +// The opcode evaluator proceeds from the top, evaluating each opcode in +// sequence. An opcode group is evaluated until the first comparison that +// returns false. At that point the rest of the group is skipped and evaluation +// resumes with the first comparison of the next group. When all the comparisons +// in a group have evaluated to true and the action is reached. The group is +// considered a matching group. +// +// In the 'ShortEval' mode evaluation stops when it reaches the end or the first +// matching group. The action opcode from this group is the resulting policy +// action. +// +// In the 'RankedEval' mode evaluation stops only when it reaches the end of the +// the opcode stream. In the process all matching groups are saved and at the +// end the 'best' group is selected (what makes the best is TBD) and the action +// from this group is the resulting policy action. +// +// As explained above, the policy evaluation of a group is a logical AND of +// the evaluation of each opcode. However an opcode can request kPolUseOREval +// which makes the evaluation to use logical OR. Given that each opcode can +// request its evaluation result to be negated with kPolNegateEval you can +// achieve the negation of the total group evaluation. This means that if you +// need to express: +// if (!(c1 && c2 && c3)) +// You can do it by: +// if ((!c1) || (!c2) || (!c3)) +// + +// Possible outcomes of policy evaluation. +enum PolicyResult { + NO_POLICY_MATCH, + POLICY_MATCH, + POLICY_ERROR +}; + +// Policy evaluation flags +// TODO(cpu): implement the options 0 & 4. +// +// Stop evaluating as soon as an error is encountered. +const uint32 kStopOnErrors = 0; +// Ignore all non fatal opcode evaluation errors. +const uint32 kIgnoreErrors = 1; +// Short-circuit evaluation: Only evaluate until opcode group that +// evaluated to true has been found. +const uint32 kShortEval = 2; +// Discussed briefly at the policy design meeting. It will evaluate +// all rules and then return the 'best' rule that evaluated true. +const uint32 kRankedEval = 4; + +// This class evaluates a policy-opcode stream given the memory where the +// opcodes are and an input 'parameter set'. +// +// This class is designed to be callable from interception points +// as low as the NtXXXX service level (it is not currently safe, but +// it is designed to be made safe). +// +// Its usage in an interception is: +// +// POLPARAMS_BEGIN(eval_params) +// POLPARAM(param1) +// POLPARAM(param2) +// POLPARAM(param3) +// POLPARAM(param4) +// POLPARAM(param5) +// POLPARAMS_END; +// +// PolicyProcessor pol_evaluator(policy_memory); +// PolicyResult pr = pol_evaluator.Evaluate(ShortEval, eval_params, +// _countof(eval_params)); +// if (NO_POLICY_MATCH == pr) { +// EvalResult policy_action = pol_evaluator.GetAction(); +// // apply policy here... +// } +// +// Where the POLPARAM() arguments are derived from the intercepted function +// arguments, and represent all the 'interesting' policy inputs, and +// policy_memory is a memory buffer containing the opcode stream that is the +// relevant policy for this intercept. +class PolicyProcessor { + public: + // policy_buffer contains opcodes made with OpcodeFactory. They are usually + // created in the broker process and evaluated in the target process. + + // This constructor is just a variant of the previous constructor. + explicit PolicyProcessor(PolicyBuffer* policy) + : policy_(policy) { + SetInternalState(0, EVAL_FALSE); + } + + // Evaluates a policy-opcode stream. See the comments at the top of this + // class for more info. Returns POLICY_MATCH if a rule set was found that + // matches an active policy. + PolicyResult Evaluate(uint32 options, + ParameterSet* parameters, + size_t parameter_count); + + // If the result of Evaluate() was POLICY_MATCH, calling this function returns + // the recommended policy action. + EvalResult GetAction() const; + + private: + struct { + size_t current_index_; + EvalResult current_result_; + } state_; + + // Sets the currently matching action result. + void SetInternalState(size_t index, EvalResult result); + + PolicyBuffer* policy_; + DISALLOW_EVIL_CONSTRUCTORS(PolicyProcessor); +}; + +} // namespace sandbox + +#endif // SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__ |