policy_engine_params.h 6.2 KB

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