diff options
Diffstat (limited to 'security/sandbox/chromium/sandbox/win/src/policy_engine_opcodes.h')
-rw-r--r-- | security/sandbox/chromium/sandbox/win/src/policy_engine_opcodes.h | 388 |
1 files changed, 0 insertions, 388 deletions
diff --git a/security/sandbox/chromium/sandbox/win/src/policy_engine_opcodes.h b/security/sandbox/chromium/sandbox/win/src/policy_engine_opcodes.h deleted file mode 100644 index 11a9c813e..000000000 --- a/security/sandbox/chromium/sandbox/win/src/policy_engine_opcodes.h +++ /dev/null @@ -1,388 +0,0 @@ -// 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 <stddef.h> -#include <stdint.h> - -#include "base/macros.h" -#include "base/numerics/safe_conversions.h" -#include "sandbox/win/src/policy_engine_params.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_NUMBER_MATCH_RANGE, // Match a 32-bit integer as a <= n <= b. - OP_NUMBER_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_t kPolNone = 0; - -// Convert EVAL_TRUE into EVAL_FALSE and vice-versa. This allows to express -// negated conditions such as if ( a && !b). -const uint32_t kPolNegateEval = 1; - -// Zero the MatchContext context structure. This happens after the opcode -// is evaluated. -const uint32_t 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_t 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_t 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 { - static_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) { - static_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_t GetOptions() const { return options_; } - - // Sets the stored options such as kPolNegateEval. - void SetOptions(uint32_t options) { - options_ = base::checked_cast<uint16_t>(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_t parameter_; - // TODO(cpu): Making |options_| a uint32_t would avoid casting, but causes - // test failures. Somewhere code is relying on the size of this struct. - // http://crbug.com/420296 - uint16_t 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_t options); - - // Creates an OpAlwaysFalse opcode. - PolicyOpcode* MakeOpAlwaysTrue(uint32_t options); - - // Creates an OpAction opcode. - // action: The action to return when Evaluate() is called. - PolicyOpcode* MakeOpAction(EvalResult action, uint32_t options); - - // Creates an OpNumberMatch opcode. - // selected_param: index of the input argument. It must be a uint32_t or the - // evaluation result will generate a EVAL_ERROR. - // match: the number to compare against the selected_param. - PolicyOpcode* MakeOpNumberMatch(int16_t selected_param, - uint32_t match, - uint32_t 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_t selected_param, - const void* match, - uint32_t options); - - // Creates an OpNumberMatchRange opcode using the memory passed in the ctor. - // selected_param: index of the input argument. It must be a uint32_t or the - // evaluation result will generate a EVAL_ERROR. - // lower_bound, upper_bound: the range to compare against selected_param. - PolicyOpcode* MakeOpNumberMatchRange(int16_t selected_param, - uint32_t lower_bound, - uint32_t upper_bound, - uint32_t 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_t selected_param, - const wchar_t* match_str, - int start_position, - StringMatchOptions match_opts, - uint32_t options); - - // Creates an OpNumberAndMatch opcode using the raw memory passed in the ctor. - // selected_param: index of the input argument. It must be uint32_t or the - // evaluation result will generate a EVAL_ERROR. - // match: the value to bitwise AND against selected_param. - PolicyOpcode* MakeOpNumberAndMatch(int16_t selected_param, - uint32_t match, - uint32_t 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_t options, - int16_t 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_ |