1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/sandbox_nt_util.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,185 @@ 1.4 +// Copyright (c) 2010 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef SANDBOX_SRC_SANDBOX_NT_UTIL_H_ 1.9 +#define SANDBOX_SRC_SANDBOX_NT_UTIL_H_ 1.10 + 1.11 +#include <intrin.h> 1.12 + 1.13 +#include "base/basictypes.h" 1.14 +#include "sandbox/win/src/nt_internals.h" 1.15 +#include "sandbox/win/src/sandbox_nt_types.h" 1.16 + 1.17 +// Placement new and delete to be used from ntdll interception code. 1.18 +void* __cdecl operator new(size_t size, sandbox::AllocationType type, 1.19 + void* near_to = NULL); 1.20 +void __cdecl operator delete(void* memory, sandbox::AllocationType type); 1.21 +// Add operator delete that matches the placement form of the operator new 1.22 +// above. This is required by compiler to generate code to call operator delete 1.23 +// in case the object's constructor throws an exception. 1.24 +// See http://msdn.microsoft.com/en-us/library/cxdxz3x6.aspx 1.25 +void __cdecl operator delete(void* memory, sandbox::AllocationType type, 1.26 + void* near_to); 1.27 + 1.28 +// Regular placement new and delete 1.29 +void* __cdecl operator new(size_t size, void* buffer, 1.30 + sandbox::AllocationType type); 1.31 +void __cdecl operator delete(void* memory, void* buffer, 1.32 + sandbox::AllocationType type); 1.33 + 1.34 +// DCHECK_NT is defined to be pretty much an assert at this time because we 1.35 +// don't have logging from the ntdll layer on the child. 1.36 +// 1.37 +// VERIFY_NT and VERIFY_SUCCESS_NT are the standard asserts on debug, but 1.38 +// execute the actual argument on release builds. VERIFY_NT expects an action 1.39 +// returning a bool, while VERIFY_SUCCESS_NT expects an action returning 1.40 +// NTSTATUS. 1.41 +#ifndef NDEBUG 1.42 +#define DCHECK_NT(condition) { (condition) ? (void)0 : __debugbreak(); } 1.43 +#define VERIFY(action) DCHECK_NT(action) 1.44 +#define VERIFY_SUCCESS(action) DCHECK_NT(NT_SUCCESS(action)) 1.45 +#else 1.46 +#define DCHECK_NT(condition) 1.47 +#define VERIFY(action) (action) 1.48 +#define VERIFY_SUCCESS(action) (action) 1.49 +#endif 1.50 + 1.51 +#define NOTREACHED_NT() DCHECK_NT(false) 1.52 + 1.53 +namespace sandbox { 1.54 + 1.55 +#if defined(_M_X64) 1.56 +#pragma intrinsic(_InterlockedCompareExchange) 1.57 +#pragma intrinsic(_InterlockedCompareExchangePointer) 1.58 + 1.59 +#elif defined(_M_IX86) 1.60 +extern "C" long _InterlockedCompareExchange(long volatile* destination, 1.61 + long exchange, long comperand); 1.62 + 1.63 +#pragma intrinsic(_InterlockedCompareExchange) 1.64 + 1.65 +// We want to make sure that we use an intrinsic version of the function, not 1.66 +// the one provided by kernel32. 1.67 +__forceinline void* _InterlockedCompareExchangePointer( 1.68 + void* volatile* destination, void* exchange, void* comperand) { 1.69 + size_t ret = _InterlockedCompareExchange( 1.70 + reinterpret_cast<long volatile*>(destination), 1.71 + static_cast<long>(reinterpret_cast<size_t>(exchange)), 1.72 + static_cast<long>(reinterpret_cast<size_t>(comperand))); 1.73 + 1.74 + return reinterpret_cast<void*>(static_cast<size_t>(ret)); 1.75 +} 1.76 + 1.77 +#else 1.78 +#error Architecture not supported. 1.79 + 1.80 +#endif 1.81 + 1.82 +// Returns a pointer to the IPC shared memory. 1.83 +void* GetGlobalIPCMemory(); 1.84 + 1.85 +// Returns a pointer to the Policy shared memory. 1.86 +void* GetGlobalPolicyMemory(); 1.87 + 1.88 +enum RequiredAccess { 1.89 + READ, 1.90 + WRITE 1.91 +}; 1.92 + 1.93 +// Performs basic user mode buffer validation. In any case, buffers access must 1.94 +// be protected by SEH. intent specifies if the buffer should be tested for read 1.95 +// or write. 1.96 +// Note that write intent implies destruction of the buffer content (we actually 1.97 +// write) 1.98 +bool ValidParameter(void* buffer, size_t size, RequiredAccess intent); 1.99 + 1.100 + 1.101 +// Copies data from a user buffer to our buffer. Returns the operation status. 1.102 +NTSTATUS CopyData(void* destination, const void* source, size_t bytes); 1.103 + 1.104 +// Copies the name from an object attributes. 1.105 +NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object, 1.106 + wchar_t** out_name, uint32* attributes, HANDLE* root); 1.107 + 1.108 +// Initializes our ntdll level heap 1.109 +bool InitHeap(); 1.110 + 1.111 +// Returns true if the provided handle refers to the current process. 1.112 +bool IsSameProcess(HANDLE process); 1.113 + 1.114 +enum MappedModuleFlags { 1.115 + MODULE_IS_PE_IMAGE = 1, // Module is an executable. 1.116 + MODULE_HAS_ENTRY_POINT = 2, // Execution entry point found. 1.117 + MODULE_HAS_CODE = 4 // Non zero size of executable sections. 1.118 +}; 1.119 + 1.120 +// Returns the name and characteristics for a given PE module. The return 1.121 +// value is the name as defined by the export table and the flags is any 1.122 +// combination of the MappedModuleFlags enumeration. 1.123 +// 1.124 +// The returned buffer must be freed with a placement delete from the ntdll 1.125 +// level allocator: 1.126 +// 1.127 +// UNICODE_STRING* name = GetPEImageInfoFromModule(HMODULE module, &flags); 1.128 +// if (!name) { 1.129 +// // probably not a valid dll 1.130 +// return; 1.131 +// } 1.132 +// InsertYourLogicHere(name); 1.133 +// operator delete(name, NT_ALLOC); 1.134 +UNICODE_STRING* GetImageInfoFromModule(HMODULE module, uint32* flags); 1.135 + 1.136 +// Returns the full path and filename for a given dll. 1.137 +// May return NULL if the provided address is not backed by a named section, or 1.138 +// if the current OS version doesn't support the call. The returned buffer must 1.139 +// be freed with a placement delete (see GetImageNameFromModule example). 1.140 +UNICODE_STRING* GetBackingFilePath(PVOID address); 1.141 + 1.142 +// Returns the last component of a path that contains the module name. 1.143 +// It will return NULL if the path ends with the path separator. The returned 1.144 +// buffer must be freed with a placement delete (see GetImageNameFromModule 1.145 +// example). 1.146 +UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path); 1.147 + 1.148 +// Returns true if the parameters correspond to a dll mapped as code. 1.149 +bool IsValidImageSection(HANDLE section, PVOID *base, PLARGE_INTEGER offset, 1.150 + PSIZE_T view_size); 1.151 + 1.152 +// Converts an ansi string to an UNICODE_STRING. 1.153 +UNICODE_STRING* AnsiToUnicode(const char* string); 1.154 + 1.155 +// Provides a simple way to temporarily change the protection of a memory page. 1.156 +class AutoProtectMemory { 1.157 + public: 1.158 + AutoProtectMemory() 1.159 + : changed_(false), address_(NULL), bytes_(0), old_protect_(0) {} 1.160 + 1.161 + ~AutoProtectMemory() { 1.162 + RevertProtection(); 1.163 + } 1.164 + 1.165 + // Sets the desired protection of a given memory range. 1.166 + NTSTATUS ChangeProtection(void* address, size_t bytes, ULONG protect); 1.167 + 1.168 + // Restores the original page protection. 1.169 + NTSTATUS RevertProtection(); 1.170 + 1.171 + private: 1.172 + bool changed_; 1.173 + void* address_; 1.174 + size_t bytes_; 1.175 + ULONG old_protect_; 1.176 + 1.177 + DISALLOW_COPY_AND_ASSIGN(AutoProtectMemory); 1.178 +}; 1.179 + 1.180 +// Returns true if the file_rename_information structure is supported by our 1.181 +// rename handler. 1.182 +bool IsSupportedRenameCall(FILE_RENAME_INFORMATION* file_info, DWORD length, 1.183 + uint32 file_info_class); 1.184 + 1.185 +} // namespace sandbox 1.186 + 1.187 + 1.188 +#endif // SANDBOX_SRC_SANDBOX_NT_UTIL_H__