policy_engine_processor.h 5.3 KB

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