OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 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 | |
5 #ifndef SANDBOX_SRC_POLICY_LOW_LEVEL_H__ | |
6 #define SANDBOX_SRC_POLICY_LOW_LEVEL_H__ | |
7 | |
8 #include <stddef.h> | |
9 #include <stdint.h> | |
10 | |
11 #include <list> | |
12 | |
13 #include "base/macros.h" | |
14 #include "base/strings/string16.h" | |
15 #include "sandbox/win/src/ipc_tags.h" | |
16 #include "sandbox/win/src/policy_engine_opcodes.h" | |
17 #include "sandbox/win/src/policy_engine_params.h" | |
18 | |
19 // Low level policy classes. | |
20 // Built on top of the PolicyOpcode and OpcodeFatory, the low level policy | |
21 // provides a way to define rules on strings and numbers but it is unaware | |
22 // of Windows specific details or how the Interceptions must be set up. | |
23 // To use these classes you construct one or more rules and add them to the | |
24 // LowLevelPolicy object like this: | |
25 // | |
26 // PolicyRule rule1(ASK_BROKER); | |
27 // rule1.AddStringMatch(IF, 0, L"\\\\/?/?\\c:\\*Microsoft*\\*.exe", true); | |
28 // rule1.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL); | |
29 // rule1.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL); | |
30 // | |
31 // PolicyRule rule2(FAKE_SUCCESS); | |
32 // rule2.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*", false)); | |
33 // rule2.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL)); | |
34 // | |
35 // LowLevelPolicy policyGen(*policy_memory); | |
36 // policyGen.AddRule(kNtCreateFileSvc, &rule1); | |
37 // policyGen.AddRule(kNtCreateFileSvc, &rule2); | |
38 // policyGen.Done(); | |
39 // | |
40 // At this point (error checking omitted) the policy_memory can be copied | |
41 // to the target process where it can be evaluated. | |
42 | |
43 namespace sandbox { | |
44 | |
45 // TODO(cpu): Move this constant to crosscall_client.h. | |
46 const size_t kMaxServiceCount = 32; | |
47 static_assert(IPC_LAST_TAG <= kMaxServiceCount, | |
48 "kMaxServiceCount is too low"); | |
49 | |
50 // Defines the memory layout of the policy. This memory is filled by | |
51 // LowLevelPolicy object. | |
52 // For example: | |
53 // | |
54 // [Service 0] --points to---\ | |
55 // [Service 1] --------------|-----\ | |
56 // ...... | | | |
57 // [Service N] | | | |
58 // [data_size] | | | |
59 // [Policy Buffer 0] <-------/ | | |
60 // [opcodes of] | | |
61 // ....... | | |
62 // [Policy Buffer 1] <-------------/ | |
63 // [opcodes] | |
64 // ....... | |
65 // ....... | |
66 // [Policy Buffer N] | |
67 // [opcodes] | |
68 // ....... | |
69 // <possibly unused space here> | |
70 // ....... | |
71 // [opcode string ] | |
72 // [opcode string ] | |
73 // ....... | |
74 // [opcode string ] | |
75 struct PolicyGlobal { | |
76 PolicyBuffer* entry[kMaxServiceCount]; | |
77 size_t data_size; | |
78 PolicyBuffer data[1]; | |
79 }; | |
80 | |
81 class PolicyRule; | |
82 | |
83 // Provides the means to collect rules into a policy store (memory) | |
84 class LowLevelPolicy { | |
85 public: | |
86 // policy_store: must contain allocated memory and the internal | |
87 // size fields set to correct values. | |
88 explicit LowLevelPolicy(PolicyGlobal* policy_store); | |
89 | |
90 // Destroys all the policy rules. | |
91 ~LowLevelPolicy(); | |
92 | |
93 // Adds a rule to be generated when Done() is called. | |
94 // service: The id of the service that this rule is associated with, | |
95 // for example the 'Open Thread' service or the "Create File" service. | |
96 // returns false on error. | |
97 bool AddRule(int service, PolicyRule* rule); | |
98 | |
99 // Generates all the rules added with AddRule() into the memory area | |
100 // passed on the constructor. Returns false on error. | |
101 bool Done(); | |
102 | |
103 private: | |
104 struct RuleNode { | |
105 const PolicyRule* rule; | |
106 int service; | |
107 }; | |
108 std::list<RuleNode> rules_; | |
109 PolicyGlobal* policy_store_; | |
110 DISALLOW_IMPLICIT_CONSTRUCTORS(LowLevelPolicy); | |
111 }; | |
112 | |
113 // There are 'if' rules and 'if not' comparisons | |
114 enum RuleType { | |
115 IF = 0, | |
116 IF_NOT = 1, | |
117 }; | |
118 | |
119 // Possible comparisons for numbers | |
120 enum RuleOp { | |
121 EQUAL, | |
122 AND, | |
123 RANGE // TODO(cpu): Implement this option. | |
124 }; | |
125 | |
126 // Provides the means to collect a set of comparisons into a single | |
127 // rule and its associated action. | |
128 class PolicyRule { | |
129 friend class LowLevelPolicy; | |
130 | |
131 public: | |
132 explicit PolicyRule(EvalResult action); | |
133 PolicyRule(const PolicyRule& other); | |
134 ~PolicyRule(); | |
135 | |
136 // Adds a string comparison to the rule. | |
137 // rule_type: possible values are IF and IF_NOT. | |
138 // parameter: the expected index of the argument for this rule. For example | |
139 // in a 'create file' service the file name argument can be at index 0. | |
140 // string: is the desired matching pattern. | |
141 // match_opts: if the pattern matching is case sensitive or not. | |
142 bool AddStringMatch(RuleType rule_type, | |
143 int16_t parameter, | |
144 const wchar_t* string, | |
145 StringMatchOptions match_opts); | |
146 | |
147 // Adds a number match comparison to the rule. | |
148 // rule_type: possible values are IF and IF_NOT. | |
149 // parameter: the expected index of the argument for this rule. | |
150 // number: the value to compare the input to. | |
151 // comparison_op: the comparison kind (equal, logical and, etc). | |
152 bool AddNumberMatch(RuleType rule_type, | |
153 int16_t parameter, | |
154 uint32_t number, | |
155 RuleOp comparison_op); | |
156 | |
157 // Returns the number of opcodes generated so far. | |
158 size_t GetOpcodeCount() const { | |
159 return buffer_->opcode_count; | |
160 } | |
161 | |
162 // Called when there is no more comparisons to add. Internally it generates | |
163 // the last opcode (the action opcode). Returns false if this operation fails. | |
164 bool Done(); | |
165 | |
166 private: | |
167 void operator=(const PolicyRule&); | |
168 // Called in a loop from AddStringMatch to generate the required string | |
169 // match opcodes. rule_type, match_opts and parameter are the same as | |
170 // in AddStringMatch. | |
171 bool GenStringOpcode(RuleType rule_type, | |
172 StringMatchOptions match_opts, | |
173 uint16_t parameter, | |
174 int state, | |
175 bool last_call, | |
176 int* skip_count, | |
177 base::string16* fragment); | |
178 | |
179 // Loop over all generated opcodes and copy them to increasing memory | |
180 // addresses from opcode_start and copy the extra data (strings usually) into | |
181 // decreasing addresses from data_start. Extra data is only present in the | |
182 // string evaluation opcodes. | |
183 bool RebindCopy(PolicyOpcode* opcode_start, size_t opcode_size, | |
184 char* data_start, size_t* data_size) const; | |
185 PolicyBuffer* buffer_; | |
186 OpcodeFactory* opcode_factory_; | |
187 EvalResult action_; | |
188 bool done_; | |
189 }; | |
190 | |
191 } // namespace sandbox | |
192 | |
193 #endif // SANDBOX_SRC_POLICY_LOW_LEVEL_H__ | |
OLD | NEW |