michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__ michael@0: #define SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__ michael@0: michael@0: #include "base/basictypes.h" michael@0: #include "sandbox/win/src/internal_types.h" michael@0: #include "sandbox/win/src/nt_internals.h" michael@0: #include "sandbox/win/src/sandbox_nt_util.h" michael@0: michael@0: // This header defines the classes that allow the low level policy to select michael@0: // the input parameters. In order to better make sense of this header is michael@0: // recommended that you check policy_engine_opcodes.h first. michael@0: michael@0: namespace sandbox { michael@0: michael@0: // Models the set of interesting parameters of an intercepted system call michael@0: // normally you don't create objects of this class directly, instead you michael@0: // use the POLPARAMS_XXX macros. michael@0: // For example, if an intercepted function has the following signature: michael@0: // michael@0: // NTSTATUS NtOpenFileFunction (PHANDLE FileHandle, michael@0: // ACCESS_MASK DesiredAccess, michael@0: // POBJECT_ATTRIBUTES ObjectAttributes, michael@0: // PIO_STATUS_BLOCK IoStatusBlock, michael@0: // ULONG ShareAccess, michael@0: // ULONG OpenOptions); michael@0: // michael@0: // You could say that the following parameters are of interest to policy: michael@0: // michael@0: // POLPARAMS_BEGIN(open_params) michael@0: // POLPARAM(DESIRED_ACCESS) michael@0: // POLPARAM(OBJECT_NAME) michael@0: // POLPARAM(SECURITY_DESCRIPTOR) michael@0: // POLPARAM(IO_STATUS) michael@0: // POLPARAM(OPEN_OPTIONS) michael@0: // POLPARAMS_END; michael@0: // michael@0: // and the actual code will use this for defining the parameters: michael@0: // michael@0: // CountedParameterSet p; michael@0: // p[open_params::DESIRED_ACCESS] = ParamPickerMake(DesiredAccess); michael@0: // p[open_params::OBJECT_NAME] = michael@0: // ParamPickerMake(ObjectAttributes->ObjectName); michael@0: // p[open_params::SECURITY_DESCRIPTOR] = michael@0: // ParamPickerMake(ObjectAttributes->SecurityDescriptor); michael@0: // p[open_params::IO_STATUS] = ParamPickerMake(IoStatusBlock); michael@0: // p[open_params::OPEN_OPTIONS] = ParamPickerMake(OpenOptions); michael@0: // michael@0: // These will create an stack-allocated array of ParameterSet objects which michael@0: // have each 1) the address of the parameter 2) a numeric id that encodes the michael@0: // original C++ type. This allows the policy to treat any set of supported michael@0: // argument types uniformily and with some type safety. michael@0: // michael@0: // TODO(cpu): support not fully implemented yet for unicode string and will michael@0: // probably add other types as well. michael@0: class ParameterSet { michael@0: public: michael@0: ParameterSet() : real_type_(INVALID_TYPE), address_(NULL) {} michael@0: michael@0: // Retrieve the stored parameter. If the type does not match ulong fail. michael@0: bool Get(unsigned long* destination) const { michael@0: if (ULONG_TYPE != real_type_) { michael@0: return false; michael@0: } michael@0: *destination = Void2TypePointerCopy(); michael@0: return true; michael@0: } michael@0: michael@0: // Retrieve the stored parameter. If the type does not match void* fail. michael@0: bool Get(const void** destination) const { michael@0: if (VOIDPTR_TYPE != real_type_) { michael@0: return false; michael@0: } michael@0: *destination = Void2TypePointerCopy(); michael@0: return true; michael@0: } michael@0: michael@0: // Retrieve the stored parameter. If the type does not match wchar_t* fail. michael@0: bool Get(const wchar_t** destination) const { michael@0: if (WCHAR_TYPE != real_type_) { michael@0: return false; michael@0: } michael@0: *destination = Void2TypePointerCopy(); michael@0: return true; michael@0: } michael@0: michael@0: // False if the parameter is not properly initialized. michael@0: bool IsValid() const { michael@0: return INVALID_TYPE != real_type_; michael@0: } michael@0: michael@0: protected: michael@0: // The constructor can only be called by derived types, which should michael@0: // safely provide the real_type and the address of the argument. michael@0: ParameterSet(ArgType real_type, const void* address) michael@0: : real_type_(real_type), address_(address) { michael@0: } michael@0: michael@0: private: michael@0: // This template provides the same functionality as bits_cast but michael@0: // it works with pointer while the former works only with references. michael@0: template michael@0: T Void2TypePointerCopy() const { michael@0: return *(reinterpret_cast(address_)); michael@0: } michael@0: michael@0: ArgType real_type_; michael@0: const void* address_; michael@0: }; michael@0: michael@0: // To safely infer the type, we use a set of template specializations michael@0: // in ParameterSetEx with a template function ParamPickerMake to do the michael@0: // parameter type deduction. michael@0: michael@0: // Base template class. Not implemented so using unsupported types should michael@0: // fail to compile. michael@0: template michael@0: class ParameterSetEx : public ParameterSet { michael@0: public: michael@0: ParameterSetEx(const void* address); michael@0: }; michael@0: michael@0: template<> michael@0: class ParameterSetEx : public ParameterSet { michael@0: public: michael@0: ParameterSetEx(const void* address) michael@0: : ParameterSet(VOIDPTR_TYPE, address) {} michael@0: }; michael@0: michael@0: template<> michael@0: class ParameterSetEx : public ParameterSet { michael@0: public: michael@0: ParameterSetEx(const void* address) michael@0: : ParameterSet(VOIDPTR_TYPE, address) {} michael@0: }; michael@0: michael@0: michael@0: template<> michael@0: class ParameterSetEx : public ParameterSet { michael@0: public: michael@0: ParameterSetEx(const void* address) michael@0: : ParameterSet(WCHAR_TYPE, address) {} michael@0: }; michael@0: michael@0: template<> michael@0: class ParameterSetEx : public ParameterSet { michael@0: public: michael@0: ParameterSetEx(const void* address) michael@0: : ParameterSet(WCHAR_TYPE, address) {} michael@0: }; michael@0: michael@0: michael@0: template<> michael@0: class ParameterSetEx : public ParameterSet { michael@0: public: michael@0: ParameterSetEx(const void* address) michael@0: : ParameterSet(ULONG_TYPE, address) {} michael@0: }; michael@0: michael@0: template<> michael@0: class ParameterSetEx : public ParameterSet { michael@0: public: michael@0: ParameterSetEx(const void* address) michael@0: : ParameterSet(UNISTR_TYPE, address) {} michael@0: }; michael@0: michael@0: template michael@0: ParameterSet ParamPickerMake(T& parameter) { michael@0: return ParameterSetEx(¶meter); michael@0: }; michael@0: michael@0: struct CountedParameterSetBase { michael@0: int count; michael@0: ParameterSet parameters[1]; michael@0: }; michael@0: michael@0: // This template defines the actual list of policy parameters for a given michael@0: // interception. michael@0: // Warning: This template stores the address to the actual variables, in michael@0: // other words, the values are not copied. michael@0: template michael@0: struct CountedParameterSet { michael@0: CountedParameterSet() : count(T::PolParamLast) {} michael@0: michael@0: ParameterSet& operator[](typename T::Args n) { michael@0: return parameters[n]; michael@0: } michael@0: michael@0: CountedParameterSetBase* GetBase() { michael@0: return reinterpret_cast(this); michael@0: } michael@0: michael@0: int count; michael@0: ParameterSet parameters[T::PolParamLast]; michael@0: }; michael@0: michael@0: } // namespace sandbox michael@0: michael@0: #endif // SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__