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