security/sandbox/win/src/sandbox_nt_util.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 // Copyright (c) 2010 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.
     5 #ifndef SANDBOX_SRC_SANDBOX_NT_UTIL_H_
     6 #define SANDBOX_SRC_SANDBOX_NT_UTIL_H_
     8 #include <intrin.h>
    10 #include "base/basictypes.h"
    11 #include "sandbox/win/src/nt_internals.h"
    12 #include "sandbox/win/src/sandbox_nt_types.h"
    14 // Placement new and delete to be used from ntdll interception code.
    15 void* __cdecl operator new(size_t size, sandbox::AllocationType type,
    16                            void* near_to = NULL);
    17 void __cdecl operator delete(void* memory, sandbox::AllocationType type);
    18 // Add operator delete that matches the placement form of the operator new
    19 // above. This is required by compiler to generate code to call operator delete
    20 // in case the object's constructor throws an exception.
    21 // See http://msdn.microsoft.com/en-us/library/cxdxz3x6.aspx
    22 void __cdecl operator delete(void* memory, sandbox::AllocationType type,
    23                              void* near_to);
    25 // Regular placement new and delete
    26 void* __cdecl operator new(size_t size, void* buffer,
    27                            sandbox::AllocationType type);
    28 void __cdecl operator delete(void* memory, void* buffer,
    29                              sandbox::AllocationType type);
    31 // DCHECK_NT is defined to be pretty much an assert at this time because we
    32 // don't have logging from the ntdll layer on the child.
    33 //
    34 // VERIFY_NT and VERIFY_SUCCESS_NT are the standard asserts on debug, but
    35 // execute the actual argument on release builds. VERIFY_NT expects an action
    36 // returning a bool, while VERIFY_SUCCESS_NT expects an action returning
    37 // NTSTATUS.
    38 #ifndef NDEBUG
    39 #define DCHECK_NT(condition) { (condition) ? (void)0 : __debugbreak(); }
    40 #define VERIFY(action) DCHECK_NT(action)
    41 #define VERIFY_SUCCESS(action) DCHECK_NT(NT_SUCCESS(action))
    42 #else
    43 #define DCHECK_NT(condition)
    44 #define VERIFY(action) (action)
    45 #define VERIFY_SUCCESS(action) (action)
    46 #endif
    48 #define NOTREACHED_NT() DCHECK_NT(false)
    50 namespace sandbox {
    52 #if defined(_M_X64)
    53 #pragma intrinsic(_InterlockedCompareExchange)
    54 #pragma intrinsic(_InterlockedCompareExchangePointer)
    56 #elif defined(_M_IX86)
    57 extern "C" long _InterlockedCompareExchange(long volatile* destination,
    58                                             long exchange, long comperand);
    60 #pragma intrinsic(_InterlockedCompareExchange)
    62 // We want to make sure that we use an intrinsic version of the function, not
    63 // the one provided by kernel32.
    64 __forceinline void* _InterlockedCompareExchangePointer(
    65     void* volatile* destination, void* exchange, void* comperand) {
    66   size_t ret = _InterlockedCompareExchange(
    67       reinterpret_cast<long volatile*>(destination),
    68       static_cast<long>(reinterpret_cast<size_t>(exchange)),
    69       static_cast<long>(reinterpret_cast<size_t>(comperand)));
    71   return reinterpret_cast<void*>(static_cast<size_t>(ret));
    72 }
    74 #else
    75 #error Architecture not supported.
    77 #endif
    79 // Returns a pointer to the IPC shared memory.
    80 void* GetGlobalIPCMemory();
    82 // Returns a pointer to the Policy shared memory.
    83 void* GetGlobalPolicyMemory();
    85 enum RequiredAccess {
    86   READ,
    87   WRITE
    88 };
    90 // Performs basic user mode buffer validation. In any case, buffers access must
    91 // be protected by SEH. intent specifies if the buffer should be tested for read
    92 // or write.
    93 // Note that write intent implies destruction of the buffer content (we actually
    94 // write)
    95 bool ValidParameter(void* buffer, size_t size, RequiredAccess intent);
    98 // Copies data from a user buffer to our buffer. Returns the operation status.
    99 NTSTATUS CopyData(void* destination, const void* source, size_t bytes);
   101 // Copies the name from an object attributes.
   102 NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object,
   103                           wchar_t** out_name, uint32* attributes, HANDLE* root);
   105 // Initializes our ntdll level heap
   106 bool InitHeap();
   108 // Returns true if the provided handle refers to the current process.
   109 bool IsSameProcess(HANDLE process);
   111 enum MappedModuleFlags {
   112   MODULE_IS_PE_IMAGE     = 1,   // Module is an executable.
   113   MODULE_HAS_ENTRY_POINT = 2,   // Execution entry point found.
   114   MODULE_HAS_CODE =        4    // Non zero size of executable sections.
   115 };
   117 // Returns the name and characteristics for a given PE module. The return
   118 // value is the name as defined by the export table and the flags is any
   119 // combination of the MappedModuleFlags enumeration.
   120 //
   121 // The returned buffer must be freed with a placement delete from the ntdll
   122 // level allocator:
   123 //
   124 // UNICODE_STRING* name = GetPEImageInfoFromModule(HMODULE module, &flags);
   125 // if (!name) {
   126 //   // probably not a valid dll
   127 //   return;
   128 // }
   129 // InsertYourLogicHere(name);
   130 // operator delete(name, NT_ALLOC);
   131 UNICODE_STRING* GetImageInfoFromModule(HMODULE module, uint32* flags);
   133 // Returns the full path and filename for a given dll.
   134 // May return NULL if the provided address is not backed by a named section, or
   135 // if the current OS version doesn't support the call. The returned buffer must
   136 // be freed with a placement delete (see GetImageNameFromModule example).
   137 UNICODE_STRING* GetBackingFilePath(PVOID address);
   139 // Returns the last component of a path that contains the module name.
   140 // It will return NULL if the path ends with the path separator. The returned
   141 // buffer must be freed with a placement delete (see GetImageNameFromModule
   142 // example).
   143 UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path);
   145 // Returns true if the parameters correspond to a dll mapped as code.
   146 bool IsValidImageSection(HANDLE section, PVOID *base, PLARGE_INTEGER offset,
   147                          PSIZE_T view_size);
   149 // Converts an ansi string to an UNICODE_STRING.
   150 UNICODE_STRING* AnsiToUnicode(const char* string);
   152 // Provides a simple way to temporarily change the protection of a memory page.
   153 class AutoProtectMemory {
   154  public:
   155   AutoProtectMemory()
   156       : changed_(false), address_(NULL), bytes_(0), old_protect_(0) {}
   158   ~AutoProtectMemory() {
   159     RevertProtection();
   160   }
   162   // Sets the desired protection of a given memory range.
   163   NTSTATUS ChangeProtection(void* address, size_t bytes, ULONG protect);
   165   // Restores the original page protection.
   166   NTSTATUS RevertProtection();
   168  private:
   169   bool changed_;
   170   void* address_;
   171   size_t bytes_;
   172   ULONG old_protect_;
   174   DISALLOW_COPY_AND_ASSIGN(AutoProtectMemory);
   175 };
   177 // Returns true if the file_rename_information structure is supported by our
   178 // rename handler.
   179 bool IsSupportedRenameCall(FILE_RENAME_INFORMATION* file_info, DWORD length,
   180                            uint32 file_info_class);
   182 }  // namespace sandbox
   185 #endif  // SANDBOX_SRC_SANDBOX_NT_UTIL_H__

mercurial