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