• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ParameterSet()62   ParameterSet() : real_type_(INVALID_TYPE), address_(NULL) {}
63 
64   // Retrieve the stored parameter. If the type does not match ulong fail.
Get(uint32_t * destination)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.
Get(const void ** destination)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.
Get(const wchar_t ** destination)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.
IsValid()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.
ParameterSet(ArgType real_type,const void * address)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>
Void2TypePointerCopy()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:
ParameterSetEx(const void * address)130   ParameterSetEx(const void* address)
131       : ParameterSet(VOIDPTR_TYPE, address) {}
132 };
133 
134 template<>
135 class ParameterSetEx<void*> : public ParameterSet {
136  public:
ParameterSetEx(const void * address)137   ParameterSetEx(const void* address)
138       : ParameterSet(VOIDPTR_TYPE, address) {}
139 };
140 
141 
142 template<>
143 class ParameterSetEx<wchar_t*> : public ParameterSet {
144  public:
ParameterSetEx(const void * address)145   ParameterSetEx(const void* address)
146       : ParameterSet(WCHAR_TYPE, address) {}
147 };
148 
149 template<>
150 class ParameterSetEx<wchar_t const*> : public ParameterSet {
151  public:
ParameterSetEx(const void * address)152   ParameterSetEx(const void* address)
153       : ParameterSet(WCHAR_TYPE, address) {}
154 };
155 
156 template <>
157 class ParameterSetEx<uint32_t> : public ParameterSet {
158  public:
ParameterSetEx(const void * address)159   ParameterSetEx(const void* address)
160       : ParameterSet(UINT32_TYPE, address) {}
161 };
162 
163 template<>
164 class ParameterSetEx<UNICODE_STRING> : public ParameterSet {
165  public:
ParameterSetEx(const void * address)166   ParameterSetEx(const void* address)
167       : ParameterSet(UNISTR_TYPE, address) {}
168 };
169 
170 template <typename T>
ParamPickerMake(T & parameter)171 ParameterSet ParamPickerMake(T& parameter) {
172   return ParameterSetEx<T>(&parameter);
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 {
CountedParameterSetCountedParameterSet186   CountedParameterSet() : count(T::PolParamLast) {}
187 
188   ParameterSet& operator[](typename T::Args n) {
189     return parameters[n];
190   }
191 
GetBaseCountedParameterSet192   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