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

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

mercurial