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