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 39namespace sandbox { 40 41// TODO(cpu): Move this constant to crosscall_client.h. 42const size_t kMaxServiceCount = 32; 43COMPILE_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 ] 70struct PolicyGlobal { 71 PolicyBuffer* entry[kMaxServiceCount]; 72 size_t data_size; 73 PolicyBuffer data[1]; 74}; 75 76class PolicyRule; 77 78// Provides the means to collect rules into a policy store (memory) 79class 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 111enum RuleType { 112 IF = 0, 113 IF_NOT = 1, 114}; 115 116// Possible comparisons for numbers 117enum 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. 125class 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