Home | History | Annotate | Download | only in src
      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:
     62   ParameterSet() : real_type_(INVALID_TYPE), address_(NULL) {}
     63 
     64   // Retrieve the stored parameter. If the type does not match ulong fail.
     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.
     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.
     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.
     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.
     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>
    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:
    130   ParameterSetEx(const void* address)
    131       : ParameterSet(VOIDPTR_TYPE, address) {}
    132 };
    133 
    134 template<>
    135 class ParameterSetEx<void*> : public ParameterSet {
    136  public:
    137   ParameterSetEx(const void* address)
    138       : ParameterSet(VOIDPTR_TYPE, address) {}
    139 };
    140 
    141 
    142 template<>
    143 class ParameterSetEx<wchar_t*> : public ParameterSet {
    144  public:
    145   ParameterSetEx(const void* address)
    146       : ParameterSet(WCHAR_TYPE, address) {}
    147 };
    148 
    149 template<>
    150 class ParameterSetEx<wchar_t const*> : public ParameterSet {
    151  public:
    152   ParameterSetEx(const void* address)
    153       : ParameterSet(WCHAR_TYPE, address) {}
    154 };
    155 
    156 template <>
    157 class ParameterSetEx<uint32_t> : public ParameterSet {
    158  public:
    159   ParameterSetEx(const void* address)
    160       : ParameterSet(UINT32_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>(&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 {
    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__
    203