// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SANDBOX_WIN_SRC_POLICY_ENGINE_OPCODES_H_
#define SANDBOX_WIN_SRC_POLICY_ENGINE_OPCODES_H_

#include "sandbox/win/src/policy_engine_params.h"
#include "base/basictypes.h"

// The low-level policy is implemented using the concept of policy 'opcodes'.
// An opcode is a structure that contains enough information to perform one
// comparison against one single input parameter. For example, an opcode can
// encode just one of the following comparison:
//
// - Is input parameter 3 not equal to NULL?
// - Does input parameter 2 start with L"c:\\"?
// - Is input parameter 5, bit 3 is equal 1?
//
// Each opcode is in fact equivalent to a function invocation where all
// the parameters are known by the opcode except one. So say you have a
// function of this form:
//      bool fn(a, b, c, d)  with 4 arguments
//
// Then an opcode is:
//      op(fn, b, c, d)
// Which stores the function to call and its 3 last arguments
//
// Then and opcode evaluation is:
//      op.eval(a)  ------------------------> fn(a,b,c,d)
//                        internally calls
//
// The idea is that complex policy rules can be split into streams of
// opcodes which are evaluated in sequence. The evaluation is done in
// groups of opcodes that have N comparison opcodes plus 1 action opcode:
//
// [comparison 1][comparison 2]...[comparison N][action][comparison 1]...
//    ----- evaluation order----------->
//
// Each opcode group encodes one high-level policy rule. The rule applies
// only if all the conditions on the group evaluate to true. The action
// opcode contains the policy outcome for that particular rule.
//
// Note that this header contains the main building blocks of low-level policy
// but not the low level policy class.
namespace sandbox {

// These are the possible policy outcomes. Note that some of them might
// not apply and can be removed. Also note that The following values only
// specify what to do, not how to do it and it is acceptable given specific
// cases to ignore the policy outcome.
enum EvalResult {
  // Comparison opcode values:
  EVAL_TRUE,   // Opcode condition evaluated true.
  EVAL_FALSE,  // Opcode condition evaluated false.
  EVAL_ERROR,  // Opcode condition generated an error while evaluating.
  // Action opcode values:
  ASK_BROKER,  // The target must generate an IPC to the broker. On the broker
               // side, this means grant access to the resource.
  DENY_ACCESS,   // No access granted to the resource.
  GIVE_READONLY,  // Give readonly access to the resource.
  GIVE_ALLACCESS,  // Give full access to the resource.
  GIVE_CACHED,  // IPC is not required. Target can return a cached handle.
  GIVE_FIRST,  // TODO(cpu)
  SIGNAL_ALARM,  // Unusual activity. Generate an alarm.
  FAKE_SUCCESS,  // Do not call original function. Just return 'success'.
  FAKE_ACCESS_DENIED,  // Do not call original function. Just return 'denied'
                       // and do not do IPC.
  TERMINATE_PROCESS,  // Destroy target process. Do IPC as well.
};

// The following are the implemented opcodes.
enum OpcodeID {
  OP_ALWAYS_FALSE,  // Evaluates to false (EVAL_FALSE).
  OP_ALWAYS_TRUE,  // Evaluates to true (EVAL_TRUE).
  OP_NUMBER_MATCH,  // Match a 32-bit integer as n == a.
  OP_ULONG_MATCH_RANGE,  // Match an ulong integer as a <= n <= b.
  OP_ULONG_AND_MATCH,  // Match using bitwise AND; as in: n & a != 0.
  OP_WSTRING_MATCH,  // Match a string for equality.
  OP_ACTION  // Evaluates to an action opcode.
};

// Options that apply to every opcode. They are specified when creating
// each opcode using OpcodeFactory::MakeOpXXXXX() family of functions
// Do nothing special.
const uint32 kPolNone = 0;

// Convert EVAL_TRUE into EVAL_FALSE and vice-versa. This allows to express
// negated conditions such as if ( a && !b).
const uint32 kPolNegateEval = 1;

// Zero the MatchContext context structure. This happens after the opcode
// is evaluated.
const uint32 kPolClearContext = 2;

// Use OR when evaluating this set of opcodes. The policy evaluator by default
// uses AND when evaluating. Very helpful when
// used with kPolNegateEval. For example if you have a condition best expressed
// as if(! (a && b && c)), the use of this flags allows it to be expressed as
// if ((!a) || (!b) || (!c)).
const uint32 kPolUseOREval = 4;

// Keeps the evaluation state between opcode evaluations. This is used
// for string matching where the next opcode needs to continue matching
// from the last character position from the current opcode. The match
// context is preserved across opcode evaluation unless an opcode specifies
// as an option kPolClearContext.
struct MatchContext {
  size_t position;
  uint32 options;

  MatchContext() {
    Clear();
  }

  void Clear() {
    position = 0;
    options = 0;
  }
};

// Models a policy opcode; that is a condition evaluation were all the
// arguments but one are stored in objects of this class. Use OpcodeFactory
// to create objects of this type.
// This class is just an implementation artifact and not exposed to the
// API clients or visible in the intercepted service. Internally, an
// opcode is just:
//  - An integer that identifies the actual opcode.
//  - An index to indicate which one is the input argument
//  - An array of arguments.
// While an OO hierarchy of objects would have been a natural choice, the fact
// that 1) this code can execute before the CRT is loaded, presents serious
// problems in terms of guarantees about the actual state of the vtables and
// 2) because the opcode objects are generated in the broker process, we need to
// use plain objects. To preserve some minimal type safety templates are used
// when possible.
class PolicyOpcode {
  friend class OpcodeFactory;
 public:
  // Evaluates the opcode. For a typical comparison opcode the return value
  // is EVAL_TRUE or EVAL_FALSE. If there was an error in the evaluation the
  // the return is EVAL_ERROR. If the opcode is an action opcode then the
  // return can take other values such as ASK_BROKER.
  // parameters: An array of all input parameters. This argument is normally
  // created by the macros POLPARAMS_BEGIN() POLPARAMS_END.
  // count: The number of parameters passed as first argument.
  // match: The match context that is persisted across the opcode evaluation
  // sequence.
  EvalResult Evaluate(const ParameterSet* parameters, size_t count,
                      MatchContext* match);

  // Retrieves a stored argument by index. Valid index values are
  // from 0 to < kArgumentCount.
  template <typename T>
  void GetArgument(size_t index, T* argument) const {
    COMPILE_ASSERT(sizeof(T) <= sizeof(arguments_[0]), invalid_size);
    *argument = *reinterpret_cast<const T*>(&arguments_[index].mem);
  }

  // Sets a stored argument by index. Valid index values are
  // from 0 to < kArgumentCount.
  template <typename T>
  void SetArgument(size_t index, const T& argument) {
    COMPILE_ASSERT(sizeof(T) <= sizeof(arguments_[0]), invalid_size);
    *reinterpret_cast<T*>(&arguments_[index].mem) = argument;
  }

  // Retrieves the actual address of an string argument. When using
  // GetArgument() to retrieve an index that contains a string, the returned
  // value is just an offset to the actual string.
  // index: the stored string index. Valid values are from 0
  // to < kArgumentCount.
  const wchar_t* GetRelativeString(size_t index) const {
    ptrdiff_t str_delta = 0;
    GetArgument(index, &str_delta);
    const char* delta = reinterpret_cast<const char*>(this) + str_delta;
    return reinterpret_cast<const wchar_t*>(delta);
  }

  // Returns true if this opcode is an action opcode without actually
  // evaluating it. Used to do a quick scan forward to the next opcode group.
  bool IsAction() const {
    return (OP_ACTION == opcode_id_);
  };

  // Returns the opcode type.
  OpcodeID GetID() const {
    return opcode_id_;
  }

  // Returns the stored options such as kPolNegateEval and others.
  uint32 GetOptions() const {
    return options_;
  }

  // Sets the stored options such as kPolNegateEval.
  void SetOptions(int16 options) {
    options_ = options;
  }

 private:

  static const size_t kArgumentCount = 4;  // The number of supported argument.

  struct OpcodeArgument {
    UINT_PTR mem;
  };

  // Better define placement new in the class instead of relying on the
  // global definition which seems to be fubared.
  void* operator new(size_t, void* location) {
    return location;
  }

  // Helper function to evaluate the opcode. The parameters have the same
  // meaning that in Evaluate().
  EvalResult EvaluateHelper(const ParameterSet* parameters,
                           MatchContext* match);
  OpcodeID opcode_id_;
  int16 parameter_;
  int16 options_;
  OpcodeArgument arguments_[PolicyOpcode::kArgumentCount];
};

enum StringMatchOptions {
  CASE_SENSITIVE = 0,      // Pay or Not attention to the case as defined by
  CASE_INSENSITIVE = 1,    // RtlCompareUnicodeString windows API.
  EXACT_LENGHT = 2         // Don't do substring match. Do full string match.
};

// Opcodes that do string comparisons take a parameter that is the starting
// position to perform the comparison so we can do substring matching. There
// are two special values:
//
// Start from the current position and compare strings advancing forward until
// a match is found if any. Similar to CRT strstr().
const int  kSeekForward = -1;
// Perform a match with the end of the string. It only does a single comparison.
const int  kSeekToEnd = 0xfffff;


// A PolicyBuffer is a variable size structure that contains all the opcodes
// that are to be created or evaluated in sequence.
struct PolicyBuffer {
  size_t opcode_count;
  PolicyOpcode opcodes[1];
};

// Helper class to create any opcode sequence. This class is normally invoked
// only by the high level policy module or when you need to handcraft a special
// policy.
// The factory works by creating the opcodes using a chunk of memory given
// in the constructor. The opcodes themselves are allocated from the beginning
// (top) of the memory, while any string that an opcode needs is allocated from
// the end (bottom) of the memory.
//
// In essence:
//
//   low address ---> [opcode 1]
//                    [opcode 2]
//                    [opcode 3]
//                    |        | <--- memory_top_
//                    | free   |
//                    |        |
//                    |        | <--- memory_bottom_
//                    [string 1]
//   high address --> [string 2]
//
// Note that this class does not keep track of the number of opcodes made and
// it is designed to be a building block for low-level policy.
//
// Note that any of the MakeOpXXXXX member functions below can return NULL on
// failure. When that happens opcode sequence creation must be aborted.
class OpcodeFactory {
 public:
  // memory: base pointer to a chunk of memory where the opcodes are created.
  // memory_size: the size in bytes of the memory chunk.
  OpcodeFactory(char* memory, size_t memory_size)
      : memory_top_(memory) {
    memory_bottom_ = &memory_top_[memory_size];
  }

  // policy: contains the raw memory where the opcodes are created.
  // memory_size: contains the actual size of the policy argument.
  OpcodeFactory(PolicyBuffer* policy, size_t memory_size) {
    memory_top_ = reinterpret_cast<char*>(&policy->opcodes[0]);
    memory_bottom_ = &memory_top_[memory_size];
  }

  // Returns the available memory to make opcodes.
  size_t memory_size() const {
    return memory_bottom_ - memory_top_;
  }

  // Creates an OpAlwaysFalse opcode.
  PolicyOpcode* MakeOpAlwaysFalse(uint32 options);

  // Creates an OpAlwaysFalse opcode.
  PolicyOpcode* MakeOpAlwaysTrue(uint32 options);

  // Creates an OpAction opcode.
  // action: The action to return when Evaluate() is called.
  PolicyOpcode* MakeOpAction(EvalResult action, uint32 options);

  // Creates an OpNumberMatch opcode.
  // selected_param: index of the input argument. It must be a ulong or the
  // evaluation result will generate a EVAL_ERROR.
  // match: the number to compare against the selected_param.
  PolicyOpcode* MakeOpNumberMatch(int16 selected_param, unsigned long match,
                                  uint32 options);

  // Creates an OpNumberMatch opcode (void pointers are cast to numbers).
  // selected_param: index of the input argument. It must be an void* or the
  // evaluation result will generate a EVAL_ERROR.
  // match: the pointer numeric value to compare against selected_param.
  PolicyOpcode* MakeOpVoidPtrMatch(int16 selected_param, const void* match,
                                   uint32 options);

  // Creates an OpUlongMatchRange opcode using the memory passed in the ctor.
  // selected_param: index of the input argument. It must be a ulong or the
  // evaluation result will generate a EVAL_ERROR.
  // lower_bound, upper_bound: the range to compare against selected_param.
  PolicyOpcode* MakeOpUlongMatchRange(int16 selected_param,
                                      unsigned long lower_bound,
                                      unsigned long upper_bound,
                                      uint32 options);

  // Creates an OpWStringMatch opcode using the raw memory passed in the ctor.
  // selected_param: index of the input argument. It must be a wide string
  // pointer or the evaluation result will generate a EVAL_ERROR.
  // match_str: string to compare against selected_param.
  // start_position: when its value is from 0 to < 0x7fff it indicates an
  // offset from the selected_param string where to perform the comparison. If
  // the value is SeekForward  then a substring search is performed. If the
  // value is SeekToEnd the comparison is performed against the last part of
  // the selected_param string.
  // Note that the range in the position (0 to 0x7fff) is dictated by the
  // current implementation.
  // match_opts: Indicates additional matching flags. Currently CaseInsensitive
  // is supported.
  PolicyOpcode* MakeOpWStringMatch(int16 selected_param,
                                   const wchar_t* match_str,
                                   int start_position,
                                   StringMatchOptions match_opts,
                                   uint32 options);

  // Creates an OpUlongAndMatch opcode using the raw memory passed in the ctor.
  // selected_param: index of the input argument. It must be ulong or the
  // evaluation result will generate a EVAL_ERROR.
  // match: the value to bitwise AND against selected_param.
  PolicyOpcode* MakeOpUlongAndMatch(int16 selected_param,
                                    unsigned long match,
                                    uint32 options);

 private:
  // Constructs the common part of every opcode. selected_param is the index
  // of the input param to use when evaluating the opcode. Pass -1 in
  // selected_param to indicate that no input parameter is required.
  PolicyOpcode* MakeBase(OpcodeID opcode_id, uint32 options,
                         int16 selected_param);

  // Allocates (and copies) a string (of size length) inside the buffer and
  // returns the displacement with respect to start.
  ptrdiff_t AllocRelative(void* start, const wchar_t* str, size_t lenght);

  // Points to the lowest currently available address of the memory
  // used to make the opcodes. This pointer increments as opcodes are made.
  char* memory_top_;

  // Points to the highest currently available address of the memory
  // used to make the opcodes. This pointer decrements as opcode strings are
  // allocated.
  char* memory_bottom_;

  DISALLOW_COPY_AND_ASSIGN(OpcodeFactory);
};

}  // namespace sandbox

#endif  // SANDBOX_WIN_SRC_POLICY_ENGINE_OPCODES_H_
