security/sandbox/win/src/policy_engine_params.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial