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 "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>(&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