159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Use of this source code is governed by a BSD-style license that can be
359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// found in the LICENSE file.
459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#ifndef SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__
659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__
759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
8cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include <stdint.h>
9cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko
1059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "sandbox/win/src/internal_types.h"
1159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "sandbox/win/src/nt_internals.h"
1259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "sandbox/win/src/sandbox_nt_util.h"
1359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
1459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This header defines the classes that allow the low level policy to select
1559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// the input parameters. In order to better make sense of this header is
1659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// recommended that you check policy_engine_opcodes.h first.
1759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
1859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratnamespace sandbox {
1959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
2059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Models the set of interesting parameters of an intercepted system call
2159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// normally you don't create objects of this class directly, instead you
2259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// use the POLPARAMS_XXX macros.
2359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// For example, if an intercepted function has the following signature:
2459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
2559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// NTSTATUS NtOpenFileFunction (PHANDLE FileHandle,
2659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                              ACCESS_MASK DesiredAccess,
2759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                              POBJECT_ATTRIBUTES ObjectAttributes,
2859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                              PIO_STATUS_BLOCK IoStatusBlock,
2959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                              ULONG ShareAccess,
3059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//                              ULONG OpenOptions);
3159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
3259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// You could say that the following parameters are of interest to policy:
3359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
3459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   POLPARAMS_BEGIN(open_params)
3559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//      POLPARAM(DESIRED_ACCESS)
3659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//      POLPARAM(OBJECT_NAME)
3759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//      POLPARAM(SECURITY_DESCRIPTOR)
3859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//      POLPARAM(IO_STATUS)
3959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//      POLPARAM(OPEN_OPTIONS)
4059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   POLPARAMS_END;
4159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
4259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// and the actual code will use this for defining the parameters:
4359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
4459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   CountedParameterSet<open_params> p;
4559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   p[open_params::DESIRED_ACCESS] = ParamPickerMake(DesiredAccess);
4659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   p[open_params::OBJECT_NAME] =
4759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//       ParamPickerMake(ObjectAttributes->ObjectName);
4859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   p[open_params::SECURITY_DESCRIPTOR] =
4959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//       ParamPickerMake(ObjectAttributes->SecurityDescriptor);
5059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   p[open_params::IO_STATUS] = ParamPickerMake(IoStatusBlock);
5159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//   p[open_params::OPEN_OPTIONS] = ParamPickerMake(OpenOptions);
5259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
5359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//  These will create an stack-allocated array of ParameterSet objects which
5459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//  have each 1) the address of the parameter 2) a numeric id that encodes the
5559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//  original C++ type. This allows the policy to treat any set of supported
5659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//  argument types uniformily and with some type safety.
5759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//
5859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//  TODO(cpu): support not fully implemented yet for unicode string and will
5959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat//  probably add other types as well.
6059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass ParameterSet {
6159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
6259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSet() : real_type_(INVALID_TYPE), address_(NULL) {}
6359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
6459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Retrieve the stored parameter. If the type does not match ulong fail.
65cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko  bool Get(uint32_t* destination) const {
6659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    if (real_type_ != UINT32_TYPE) {
6759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      return false;
6859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    }
69cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    *destination = Void2TypePointerCopy<uint32_t>();
7059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return true;
7159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
7259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
7359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Retrieve the stored parameter. If the type does not match void* fail.
7459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool Get(const void** destination) const {
7559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    if (real_type_ != VOIDPTR_TYPE) {
7659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      return false;
7759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    }
7859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    *destination = Void2TypePointerCopy<void*>();
7959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return true;
8059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
8159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
8259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // Retrieve the stored parameter. If the type does not match wchar_t* fail.
8359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool Get(const wchar_t** destination) const {
8459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    if (real_type_ != WCHAR_TYPE) {
8559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      return false;
8659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    }
8759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    *destination = Void2TypePointerCopy<const wchar_t*>();
8859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return true;
8959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
9059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
9159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // False if the parameter is not properly initialized.
9259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  bool IsValid() const {
9359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return real_type_ != INVALID_TYPE;
9459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
9559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
9659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat protected:
9759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // The constructor can only be called by derived types, which should
9859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // safely provide the real_type and the address of the argument.
9959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSet(ArgType real_type, const void* address)
10059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      : real_type_(real_type), address_(address) {
10159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
10259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
10359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private:
10459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // This template provides the same functionality as bits_cast but
10559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  // it works with pointer while the former works only with references.
10659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  template <typename T>
10759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  T Void2TypePointerCopy() const {
10859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return *(reinterpret_cast<const T*>(address_));
10959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
11059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
11159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ArgType real_type_;
11259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  const void* address_;
11359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
11459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
11559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// To safely infer the type, we use a set of template specializations
11659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// in ParameterSetEx with a template function ParamPickerMake to do the
11759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// parameter type deduction.
11859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
11959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Base template class. Not implemented so using unsupported types should
12059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// fail to compile.
12159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate <typename T>
12259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass ParameterSetEx : public ParameterSet {
12359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
12459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSetEx(const void* address);
12559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
12659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
12759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
12859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass ParameterSetEx<void const*> : public ParameterSet {
12959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
13059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSetEx(const void* address)
13159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      : ParameterSet(VOIDPTR_TYPE, address) {}
13259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
13359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
13459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
13559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass ParameterSetEx<void*> : public ParameterSet {
13659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
13759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSetEx(const void* address)
13859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      : ParameterSet(VOIDPTR_TYPE, address) {}
13959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
14059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
14159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
14259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
14359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass ParameterSetEx<wchar_t*> : public ParameterSet {
14459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
14559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSetEx(const void* address)
14659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      : ParameterSet(WCHAR_TYPE, address) {}
14759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
14859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
14959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
15059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass ParameterSetEx<wchar_t const*> : public ParameterSet {
15159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
15259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSetEx(const void* address)
15359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      : ParameterSet(WCHAR_TYPE, address) {}
15459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
15559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
156cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkotemplate <>
157cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkoclass ParameterSetEx<uint32_t> : public ParameterSet {
15859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
15959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSetEx(const void* address)
16059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      : ParameterSet(UINT32_TYPE, address) {}
16159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
16259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
16359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate<>
16459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass ParameterSetEx<UNICODE_STRING> : public ParameterSet {
16559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public:
16659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSetEx(const void* address)
16759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat      : ParameterSet(UNISTR_TYPE, address) {}
16859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
16959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
17059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate <typename T>
17159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel EratParameterSet ParamPickerMake(T& parameter) {
17259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  return ParameterSetEx<T>(&parameter);
17359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
17459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
17559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratstruct CountedParameterSetBase {
17659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  int count;
17759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSet parameters[1];
17859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
17959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
18059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// This template defines the actual list of policy parameters for a given
18159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// interception.
18259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Warning: This template stores the address to the actual variables, in
18359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// other words, the values are not copied.
18459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattemplate <typename T>
18559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratstruct CountedParameterSet {
18659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CountedParameterSet() : count(T::PolParamLast) {}
18759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
18859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSet& operator[](typename T::Args n) {
18959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return parameters[n];
19059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
19159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
19259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  CountedParameterSetBase* GetBase() {
19359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat    return reinterpret_cast<CountedParameterSetBase*>(this);
19459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  }
19559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
19659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  int count;
19759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat  ParameterSet parameters[T::PolParamLast];
19859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat};
19959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
20059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}  // namespace sandbox
20159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat
20259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif  // SANDBOX_SRC_POLICY_ENGINE_PARAMS_H__
203