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