1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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__
|