summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium/sandbox/win/src/policy_engine_processor.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium/sandbox/win/src/policy_engine_processor.h')
-rw-r--r--security/sandbox/chromium/sandbox/win/src/policy_engine_processor.h143
1 files changed, 143 insertions, 0 deletions
diff --git a/security/sandbox/chromium/sandbox/win/src/policy_engine_processor.h b/security/sandbox/chromium/sandbox/win/src/policy_engine_processor.h
new file mode 100644
index 0000000000..b62973b14a
--- /dev/null
+++ b/security/sandbox/chromium/sandbox/win/src/policy_engine_processor.h
@@ -0,0 +1,143 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__
+#define SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "sandbox/win/src/policy_engine_opcodes.h"
+#include "sandbox/win/src/policy_engine_params.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 kStopOnErrors & kRankedEval.
+//
+// Stop evaluating as soon as an error is encountered.
+const uint32_t kStopOnErrors = 1;
+// Ignore all non fatal opcode evaluation errors.
+const uint32_t kIgnoreErrors = 2;
+// Short-circuit evaluation: Only evaluate until opcode group that
+// evaluated to true has been found.
+const uint32_t kShortEval = 4;
+// Discussed briefly at the policy design meeting. It will evaluate
+// all rules and then return the 'best' rule that evaluated true.
+const uint32_t kRankedEval = 8;
+
+// 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_t 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_COPY_AND_ASSIGN(PolicyProcessor);
+};
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_POLICY_ENGINE_PROCESSOR_H__