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_ENGINE_PARAMS_H__ 6 #define SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__ 7 8 #include <stdint.h> 9 10 #include "sandbox/win/src/internal_types.h" 11 #include "sandbox/win/src/nt_internals.h" 12 #include "sandbox/win/src/sandbox_nt_util.h" 13 14 // This header defines the classes that allow the low level policy to select 15 // the input parameters. In order to better make sense of this header is 16 // recommended that you check policy_engine_opcodes.h first. 17 18 namespace sandbox { 19 20 // Models the set of interesting parameters of an intercepted system call 21 // normally you don't create objects of this class directly, instead you 22 // use the POLPARAMS_XXX macros. 23 // For example, if an intercepted function has the following signature: 24 // 25 // NTSTATUS NtOpenFileFunction (PHANDLE FileHandle, 26 // ACCESS_MASK DesiredAccess, 27 // POBJECT_ATTRIBUTES ObjectAttributes, 28 // PIO_STATUS_BLOCK IoStatusBlock, 29 // ULONG ShareAccess, 30 // ULONG OpenOptions); 31 // 32 // You could say that the following parameters are of interest to policy: 33 // 34 // POLPARAMS_BEGIN(open_params) 35 // POLPARAM(DESIRED_ACCESS) 36 // POLPARAM(OBJECT_NAME) 37 // POLPARAM(SECURITY_DESCRIPTOR) 38 // POLPARAM(IO_STATUS) 39 // POLPARAM(OPEN_OPTIONS) 40 // POLPARAMS_END; 41 // 42 // and the actual code will use this for defining the parameters: 43 // 44 // CountedParameterSet<open_params> p; 45 // p[open_params::DESIRED_ACCESS] = ParamPickerMake(DesiredAccess); 46 // p[open_params::OBJECT_NAME] = 47 // ParamPickerMake(ObjectAttributes->ObjectName); 48 // p[open_params::SECURITY_DESCRIPTOR] = 49 // ParamPickerMake(ObjectAttributes->SecurityDescriptor); 50 // p[open_params::IO_STATUS] = ParamPickerMake(IoStatusBlock); 51 // p[open_params::OPEN_OPTIONS] = ParamPickerMake(OpenOptions); 52 // 53 // These will create an stack-allocated array of ParameterSet objects which 54 // have each 1) the address of the parameter 2) a numeric id that encodes the 55 // original C++ type. This allows the policy to treat any set of supported 56 // argument types uniformily and with some type safety. 57 // 58 // TODO(cpu): support not fully implemented yet for unicode string and will 59 // probably add other types as well. 60 class ParameterSet { 61 public: 62 ParameterSet() : real_type_(INVALID_TYPE), address_(NULL) {} 63 64 // Retrieve the stored parameter. If the type does not match ulong fail. 65 bool Get(uint32_t* destination) const { 66 if (real_type_ != UINT32_TYPE) { 67 return false; 68 } 69 *destination = Void2TypePointerCopy<uint32_t>(); 70 return true; 71 } 72 73 // Retrieve the stored parameter. If the type does not match void* fail. 74 bool Get(const void** destination) const { 75 if (real_type_ != VOIDPTR_TYPE) { 76 return false; 77 } 78 *destination = Void2TypePointerCopy<void*>(); 79 return true; 80 } 81 82 // Retrieve the stored parameter. If the type does not match wchar_t* fail. 83 bool Get(const wchar_t** destination) const { 84 if (real_type_ != WCHAR_TYPE) { 85 return false; 86 } 87 *destination = Void2TypePointerCopy<const wchar_t*>(); 88 return true; 89 } 90 91 // False if the parameter is not properly initialized. 92 bool IsValid() const { 93 return real_type_ != INVALID_TYPE; 94 } 95 96 protected: 97 // The constructor can only be called by derived types, which should 98 // safely provide the real_type and the address of the argument. 99 ParameterSet(ArgType real_type, const void* address) 100 : real_type_(real_type), address_(address) { 101 } 102 103 private: 104 // This template provides the same functionality as bits_cast but 105 // it works with pointer while the former works only with references. 106 template <typename T> 107 T Void2TypePointerCopy() const { 108 return *(reinterpret_cast<const T*>(address_)); 109 } 110 111 ArgType real_type_; 112 const void* address_; 113 }; 114 115 // To safely infer the type, we use a set of template specializations 116 // in ParameterSetEx with a template function ParamPickerMake to do the 117 // parameter type deduction. 118 119 // Base template class. Not implemented so using unsupported types should 120 // fail to compile. 121 template <typename T> 122 class ParameterSetEx : public ParameterSet { 123 public: 124 ParameterSetEx(const void* address); 125 }; 126 127 template<> 128 class ParameterSetEx<void const*> : public ParameterSet { 129 public: 130 ParameterSetEx(const void* address) 131 : ParameterSet(VOIDPTR_TYPE, address) {} 132 }; 133 134 template<> 135 class ParameterSetEx<void*> : public ParameterSet { 136 public: 137 ParameterSetEx(const void* address) 138 : ParameterSet(VOIDPTR_TYPE, address) {} 139 }; 140 141 142 template<> 143 class ParameterSetEx<wchar_t*> : public ParameterSet { 144 public: 145 ParameterSetEx(const void* address) 146 : ParameterSet(WCHAR_TYPE, address) {} 147 }; 148 149 template<> 150 class ParameterSetEx<wchar_t const*> : public ParameterSet { 151 public: 152 ParameterSetEx(const void* address) 153 : ParameterSet(WCHAR_TYPE, address) {} 154 }; 155 156 template <> 157 class ParameterSetEx<uint32_t> : public ParameterSet { 158 public: 159 ParameterSetEx(const void* address) 160 : ParameterSet(UINT32_TYPE, address) {} 161 }; 162 163 template<> 164 class ParameterSetEx<UNICODE_STRING> : public ParameterSet { 165 public: 166 ParameterSetEx(const void* address) 167 : ParameterSet(UNISTR_TYPE, address) {} 168 }; 169 170 template <typename T> 171 ParameterSet ParamPickerMake(T& parameter) { 172 return ParameterSetEx<T>(¶meter); 173 }; 174 175 struct CountedParameterSetBase { 176 int count; 177 ParameterSet parameters[1]; 178 }; 179 180 // This template defines the actual list of policy parameters for a given 181 // interception. 182 // Warning: This template stores the address to the actual variables, in 183 // other words, the values are not copied. 184 template <typename T> 185 struct CountedParameterSet { 186 CountedParameterSet() : count(T::PolParamLast) {} 187 188 ParameterSet& operator[](typename T::Args n) { 189 return parameters[n]; 190 } 191 192 CountedParameterSetBase* GetBase() { 193 return reinterpret_cast<CountedParameterSetBase*>(this); 194 } 195 196 int count; 197 ParameterSet parameters[T::PolParamLast]; 198 }; 199 200 } // namespace sandbox 201 202 #endif // SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__ 203