1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/policy_engine_processor.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,145 @@ 1.4 +// Copyright (c) 2010 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 +#ifndef SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__ 1.9 +#define SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__ 1.10 + 1.11 +#include "base/basictypes.h" 1.12 +#include "sandbox/win/src/policy_engine_params.h" 1.13 +#include "sandbox/win/src/policy_engine_opcodes.h" 1.14 + 1.15 +namespace sandbox { 1.16 + 1.17 +// This header contains the core policy evaluator. In its simplest form 1.18 +// it evaluates a stream of opcodes assuming that they are laid out in 1.19 +// memory as opcode groups. 1.20 +// 1.21 +// An opcode group has N comparison opcodes plus 1 action opcode. For 1.22 +// example here we have 3 opcode groups (A, B,C): 1.23 +// 1.24 +// [comparison 1] <-- group A start 1.25 +// [comparison 2] 1.26 +// [comparison 3] 1.27 +// [action A ] 1.28 +// [comparison 1] <-- group B start 1.29 +// [action B ] 1.30 +// [comparison 1] <-- group C start 1.31 +// [comparison 2] 1.32 +// [action C ] 1.33 +// 1.34 +// The opcode evaluator proceeds from the top, evaluating each opcode in 1.35 +// sequence. An opcode group is evaluated until the first comparison that 1.36 +// returns false. At that point the rest of the group is skipped and evaluation 1.37 +// resumes with the first comparison of the next group. When all the comparisons 1.38 +// in a group have evaluated to true and the action is reached. The group is 1.39 +// considered a matching group. 1.40 +// 1.41 +// In the 'ShortEval' mode evaluation stops when it reaches the end or the first 1.42 +// matching group. The action opcode from this group is the resulting policy 1.43 +// action. 1.44 +// 1.45 +// In the 'RankedEval' mode evaluation stops only when it reaches the end of the 1.46 +// the opcode stream. In the process all matching groups are saved and at the 1.47 +// end the 'best' group is selected (what makes the best is TBD) and the action 1.48 +// from this group is the resulting policy action. 1.49 +// 1.50 +// As explained above, the policy evaluation of a group is a logical AND of 1.51 +// the evaluation of each opcode. However an opcode can request kPolUseOREval 1.52 +// which makes the evaluation to use logical OR. Given that each opcode can 1.53 +// request its evaluation result to be negated with kPolNegateEval you can 1.54 +// achieve the negation of the total group evaluation. This means that if you 1.55 +// need to express: 1.56 +// if (!(c1 && c2 && c3)) 1.57 +// You can do it by: 1.58 +// if ((!c1) || (!c2) || (!c3)) 1.59 +// 1.60 + 1.61 +// Possible outcomes of policy evaluation. 1.62 +enum PolicyResult { 1.63 + NO_POLICY_MATCH, 1.64 + POLICY_MATCH, 1.65 + POLICY_ERROR 1.66 +}; 1.67 + 1.68 +// Policy evaluation flags 1.69 +// TODO(cpu): implement the options 0 & 4. 1.70 +// 1.71 +// Stop evaluating as soon as an error is encountered. 1.72 +const uint32 kStopOnErrors = 0; 1.73 +// Ignore all non fatal opcode evaluation errors. 1.74 +const uint32 kIgnoreErrors = 1; 1.75 +// Short-circuit evaluation: Only evaluate until opcode group that 1.76 +// evaluated to true has been found. 1.77 +const uint32 kShortEval = 2; 1.78 +// Discussed briefly at the policy design meeting. It will evaluate 1.79 +// all rules and then return the 'best' rule that evaluated true. 1.80 +const uint32 kRankedEval = 4; 1.81 + 1.82 +// This class evaluates a policy-opcode stream given the memory where the 1.83 +// opcodes are and an input 'parameter set'. 1.84 +// 1.85 +// This class is designed to be callable from interception points 1.86 +// as low as the NtXXXX service level (it is not currently safe, but 1.87 +// it is designed to be made safe). 1.88 +// 1.89 +// Its usage in an interception is: 1.90 +// 1.91 +// POLPARAMS_BEGIN(eval_params) 1.92 +// POLPARAM(param1) 1.93 +// POLPARAM(param2) 1.94 +// POLPARAM(param3) 1.95 +// POLPARAM(param4) 1.96 +// POLPARAM(param5) 1.97 +// POLPARAMS_END; 1.98 +// 1.99 +// PolicyProcessor pol_evaluator(policy_memory); 1.100 +// PolicyResult pr = pol_evaluator.Evaluate(ShortEval, eval_params, 1.101 +// _countof(eval_params)); 1.102 +// if (NO_POLICY_MATCH == pr) { 1.103 +// EvalResult policy_action = pol_evaluator.GetAction(); 1.104 +// // apply policy here... 1.105 +// } 1.106 +// 1.107 +// Where the POLPARAM() arguments are derived from the intercepted function 1.108 +// arguments, and represent all the 'interesting' policy inputs, and 1.109 +// policy_memory is a memory buffer containing the opcode stream that is the 1.110 +// relevant policy for this intercept. 1.111 +class PolicyProcessor { 1.112 + public: 1.113 + // policy_buffer contains opcodes made with OpcodeFactory. They are usually 1.114 + // created in the broker process and evaluated in the target process. 1.115 + 1.116 + // This constructor is just a variant of the previous constructor. 1.117 + explicit PolicyProcessor(PolicyBuffer* policy) 1.118 + : policy_(policy) { 1.119 + SetInternalState(0, EVAL_FALSE); 1.120 + } 1.121 + 1.122 + // Evaluates a policy-opcode stream. See the comments at the top of this 1.123 + // class for more info. Returns POLICY_MATCH if a rule set was found that 1.124 + // matches an active policy. 1.125 + PolicyResult Evaluate(uint32 options, 1.126 + ParameterSet* parameters, 1.127 + size_t parameter_count); 1.128 + 1.129 + // If the result of Evaluate() was POLICY_MATCH, calling this function returns 1.130 + // the recommended policy action. 1.131 + EvalResult GetAction() const; 1.132 + 1.133 + private: 1.134 + struct { 1.135 + size_t current_index_; 1.136 + EvalResult current_result_; 1.137 + } state_; 1.138 + 1.139 + // Sets the currently matching action result. 1.140 + void SetInternalState(size_t index, EvalResult result); 1.141 + 1.142 + PolicyBuffer* policy_; 1.143 + DISALLOW_COPY_AND_ASSIGN(PolicyProcessor); 1.144 +}; 1.145 + 1.146 +} // namespace sandbox 1.147 + 1.148 +#endif // SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__