1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/policy_low_level.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,182 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef SANDBOX_SRC_POLICY_LOW_LEVEL_H__ 1.9 +#define SANDBOX_SRC_POLICY_LOW_LEVEL_H__ 1.10 + 1.11 +#include <list> 1.12 + 1.13 +#include "base/basictypes.h" 1.14 +#include "sandbox/win/src/ipc_tags.h" 1.15 +#include "sandbox/win/src/policy_engine_params.h" 1.16 +#include "sandbox/win/src/policy_engine_opcodes.h" 1.17 + 1.18 +// Low level policy classes. 1.19 +// Built on top of the PolicyOpcode and OpcodeFatory, the low level policy 1.20 +// provides a way to define rules on strings and numbers but it is unaware 1.21 +// of Windows specific details or how the Interceptions must be set up. 1.22 +// To use these classes you construct one or more rules and add them to the 1.23 +// LowLevelPolicy object like this: 1.24 +// 1.25 +// PolicyRule rule1(ASK_BROKER); 1.26 +// rule1.AddStringMatch(IF, 0, L"\\\\/?/?\\c:\\*Microsoft*\\*.exe", true); 1.27 +// rule1.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL); 1.28 +// rule1.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL); 1.29 +// 1.30 +// PolicyRule rule2(FAKE_SUCCESS); 1.31 +// rule2.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*", false)); 1.32 +// rule2.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL)); 1.33 +// 1.34 +// LowLevelPolicy policyGen(*policy_memory); 1.35 +// policyGen.AddRule(kNtCreateFileSvc, &rule1); 1.36 +// policyGen.AddRule(kNtCreateFileSvc, &rule2); 1.37 +// policyGen.Done(); 1.38 +// 1.39 +// At this point (error checking omitted) the policy_memory can be copied 1.40 +// to the target process where it can be evaluated. 1.41 + 1.42 +namespace sandbox { 1.43 + 1.44 +// TODO(cpu): Move this constant to crosscall_client.h. 1.45 +const size_t kMaxServiceCount = 32; 1.46 +COMPILE_ASSERT(IPC_LAST_TAG <= kMaxServiceCount, kMaxServiceCount_is_too_low); 1.47 + 1.48 +// Defines the memory layout of the policy. This memory is filled by 1.49 +// LowLevelPolicy object. 1.50 +// For example: 1.51 +// 1.52 +// [Service 0] --points to---\ 1.53 +// [Service 1] --------------|-----\ 1.54 +// ...... | | 1.55 +// [Service N] | | 1.56 +// [data_size] | | 1.57 +// [Policy Buffer 0] <-------/ | 1.58 +// [opcodes of] | 1.59 +// ....... | 1.60 +// [Policy Buffer 1] <-------------/ 1.61 +// [opcodes] 1.62 +// ....... 1.63 +// ....... 1.64 +// [Policy Buffer N] 1.65 +// [opcodes] 1.66 +// ....... 1.67 +// <possibly unused space here> 1.68 +// ....... 1.69 +// [opcode string ] 1.70 +// [opcode string ] 1.71 +// ....... 1.72 +// [opcode string ] 1.73 +struct PolicyGlobal { 1.74 + PolicyBuffer* entry[kMaxServiceCount]; 1.75 + size_t data_size; 1.76 + PolicyBuffer data[1]; 1.77 +}; 1.78 + 1.79 +class PolicyRule; 1.80 + 1.81 +// Provides the means to collect rules into a policy store (memory) 1.82 +class LowLevelPolicy { 1.83 + public: 1.84 + // policy_store: must contain allocated memory and the internal 1.85 + // size fields set to correct values. 1.86 + explicit LowLevelPolicy(PolicyGlobal* policy_store) 1.87 + : policy_store_(policy_store) { 1.88 + } 1.89 + 1.90 + // Destroys all the policy rules. 1.91 + ~LowLevelPolicy(); 1.92 + 1.93 + // Adds a rule to be generated when Done() is called. 1.94 + // service: The id of the service that this rule is associated with, 1.95 + // for example the 'Open Thread' service or the "Create File" service. 1.96 + // returns false on error. 1.97 + bool AddRule(int service, PolicyRule* rule); 1.98 + 1.99 + // Generates all the rules added with AddRule() into the memory area 1.100 + // passed on the constructor. Returns false on error. 1.101 + bool Done(); 1.102 + 1.103 + private: 1.104 + struct RuleNode { 1.105 + const PolicyRule* rule; 1.106 + int service; 1.107 + }; 1.108 + std::list<RuleNode> rules_; 1.109 + PolicyGlobal* policy_store_; 1.110 + DISALLOW_IMPLICIT_CONSTRUCTORS(LowLevelPolicy); 1.111 +}; 1.112 + 1.113 +// There are 'if' rules and 'if not' comparisons 1.114 +enum RuleType { 1.115 + IF = 0, 1.116 + IF_NOT = 1, 1.117 +}; 1.118 + 1.119 +// Possible comparisons for numbers 1.120 +enum RuleOp { 1.121 + EQUAL, 1.122 + AND, 1.123 + RANGE // TODO(cpu): Implement this option. 1.124 +}; 1.125 + 1.126 +// Provides the means to collect a set of comparisons into a single 1.127 +// rule and its associated action. 1.128 +class PolicyRule { 1.129 + friend class LowLevelPolicy; 1.130 + 1.131 + public: 1.132 + explicit PolicyRule(EvalResult action); 1.133 + PolicyRule(const PolicyRule& other); 1.134 + ~PolicyRule(); 1.135 + 1.136 + // Adds a string comparison to the rule. 1.137 + // rule_type: possible values are IF and IF_NOT. 1.138 + // parameter: the expected index of the argument for this rule. For example 1.139 + // in a 'create file' service the file name argument can be at index 0. 1.140 + // string: is the desired matching pattern. 1.141 + // match_opts: if the pattern matching is case sensitive or not. 1.142 + bool AddStringMatch(RuleType rule_type, int16 parameter, 1.143 + const wchar_t* string, StringMatchOptions match_opts); 1.144 + 1.145 + // Adds a number match comparison to the rule. 1.146 + // rule_type: possible values are IF and IF_NOT. 1.147 + // parameter: the expected index of the argument for this rule. 1.148 + // number: the value to compare the input to. 1.149 + // comparison_op: the comparison kind (equal, logical and, etc). 1.150 + bool AddNumberMatch(RuleType rule_type, int16 parameter, 1.151 + unsigned long number, RuleOp comparison_op); 1.152 + 1.153 + // Returns the number of opcodes generated so far. 1.154 + size_t GetOpcodeCount() const { 1.155 + return buffer_->opcode_count; 1.156 + } 1.157 + 1.158 + // Called when there is no more comparisons to add. Internally it generates 1.159 + // the last opcode (the action opcode). Returns false if this operation fails. 1.160 + bool Done(); 1.161 + 1.162 + private: 1.163 + void operator=(const PolicyRule&); 1.164 + // Called in a loop from AddStringMatch to generate the required string 1.165 + // match opcodes. rule_type, match_opts and parameter are the same as 1.166 + // in AddStringMatch. 1.167 + bool GenStringOpcode(RuleType rule_type, StringMatchOptions match_opts, 1.168 + uint16 parameter, int state, bool last_call, 1.169 + int* skip_count, std::wstring* fragment); 1.170 + 1.171 + // Loop over all generated opcodes and copy them to increasing memory 1.172 + // addresses from opcode_start and copy the extra data (strings usually) into 1.173 + // decreasing addresses from data_start. Extra data is only present in the 1.174 + // string evaluation opcodes. 1.175 + bool RebindCopy(PolicyOpcode* opcode_start, size_t opcode_size, 1.176 + char* data_start, size_t* data_size) const; 1.177 + PolicyBuffer* buffer_; 1.178 + OpcodeFactory* opcode_factory_; 1.179 + EvalResult action_; 1.180 + bool done_; 1.181 +}; 1.182 + 1.183 +} // namespace sandbox 1.184 + 1.185 +#endif // SANDBOX_SRC_POLICY_LOW_LEVEL_H__