summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.h')
-rw-r--r--security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.h220
1 files changed, 220 insertions, 0 deletions
diff --git a/security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.h b/security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.h
new file mode 100644
index 0000000000..70d011dfb4
--- /dev/null
+++ b/security/sandbox/chromium/sandbox/win/src/sandbox_nt_util.h
@@ -0,0 +1,220 @@
+// 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_SRC_SANDBOX_NT_UTIL_H_
+#define SANDBOX_SRC_SANDBOX_NT_UTIL_H_
+
+#include <intrin.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <memory>
+
+#include "base/macros.h"
+#include "sandbox/win/src/nt_internals.h"
+#include "sandbox/win/src/sandbox_nt_types.h"
+
+// Placement new and delete to be used from ntdll interception code.
+void* __cdecl operator new(size_t size,
+ sandbox::AllocationType type,
+ void* near_to = nullptr);
+void* __cdecl operator new[](size_t size,
+ sandbox::AllocationType type,
+ void* near_to = nullptr);
+void __cdecl operator delete(void* memory, sandbox::AllocationType type);
+// Add operator delete that matches the placement form of the operator new
+// above. This is required by compiler to generate code to call operator delete
+// in case the object's constructor throws an exception.
+// See http://msdn.microsoft.com/en-us/library/cxdxz3x6.aspx
+void __cdecl operator delete(void* memory,
+ sandbox::AllocationType type,
+ void* near_to);
+
+// Regular placement new and delete
+void* __cdecl operator new(size_t size,
+ void* buffer,
+ sandbox::AllocationType type);
+void __cdecl operator delete(void* memory,
+ void* buffer,
+ sandbox::AllocationType type);
+
+// DCHECK_NT is defined to be pretty much an assert at this time because we
+// don't have logging from the ntdll layer on the child.
+//
+// VERIFY_NT and VERIFY_SUCCESS are the standard asserts on debug, but
+// execute the actual argument on release builds. VERIFY_NT expects an action
+// returning a bool, while VERIFY_SUCCESS expects an action returning
+// NTSTATUS.
+#ifndef NDEBUG
+#define DCHECK_NT(condition) \
+ { (condition) ? (void)0 : __debugbreak(); }
+#define VERIFY(action) DCHECK_NT(action)
+#define VERIFY_SUCCESS(action) DCHECK_NT(NT_SUCCESS(action))
+#else
+#define DCHECK_NT(condition)
+#define VERIFY(action) (action)
+#define VERIFY_SUCCESS(action) (action)
+#endif
+
+#define CHECK_NT(condition) \
+ { (condition) ? (void)0 : __debugbreak(); }
+
+#define NOTREACHED_NT() DCHECK_NT(false)
+
+namespace sandbox {
+
+#if defined(_M_X64) || defined(_M_ARM64)
+#pragma intrinsic(_InterlockedCompareExchange)
+#pragma intrinsic(_InterlockedCompareExchangePointer)
+
+#elif defined(_M_IX86)
+extern "C" long _InterlockedCompareExchange(long volatile* destination,
+ long exchange,
+ long comperand);
+
+#pragma intrinsic(_InterlockedCompareExchange)
+
+// We want to make sure that we use an intrinsic version of the function, not
+// the one provided by kernel32.
+__forceinline void* _InterlockedCompareExchangePointer(
+ void* volatile* destination,
+ void* exchange,
+ void* comperand) {
+ long ret = _InterlockedCompareExchange(
+ reinterpret_cast<long volatile*>(destination),
+ static_cast<long>(reinterpret_cast<size_t>(exchange)),
+ static_cast<long>(reinterpret_cast<size_t>(comperand)));
+
+ return reinterpret_cast<void*>(static_cast<size_t>(ret));
+}
+
+#else
+#error Architecture not supported.
+
+#endif
+
+struct NtAllocDeleter {
+ inline void operator()(void* ptr) const {
+ operator delete(ptr, AllocationType::NT_ALLOC);
+ }
+};
+
+// Returns a pointer to the IPC shared memory.
+void* GetGlobalIPCMemory();
+
+// Returns a pointer to the Policy shared memory.
+void* GetGlobalPolicyMemory();
+
+enum RequiredAccess { READ, WRITE };
+
+// Performs basic user mode buffer validation. In any case, buffers access must
+// be protected by SEH. intent specifies if the buffer should be tested for read
+// or write.
+bool ValidParameter(void* buffer, size_t size, RequiredAccess intent);
+
+// Copies data from a user buffer to our buffer. Returns the operation status.
+NTSTATUS CopyData(void* destination, const void* source, size_t bytes);
+
+// Copies the name from an object attributes.
+NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object,
+ std::unique_ptr<wchar_t, NtAllocDeleter>* out_name,
+ uint32_t* attributes,
+ HANDLE* root);
+
+// Determine full path name from object root and path.
+NTSTATUS AllocAndGetFullPath(
+ HANDLE root,
+ const wchar_t* path,
+ std::unique_ptr<wchar_t, NtAllocDeleter>* full_path);
+
+// Initializes our ntdll level heap
+bool InitHeap();
+
+// Returns true if the provided handle refers to the current process.
+bool IsSameProcess(HANDLE process);
+
+enum MappedModuleFlags {
+ MODULE_IS_PE_IMAGE = 1, // Module is an executable.
+ MODULE_HAS_ENTRY_POINT = 2, // Execution entry point found.
+ MODULE_HAS_CODE = 4 // Non zero size of executable sections.
+};
+
+// Returns the name and characteristics for a given PE module. The return
+// value is the name as defined by the export table and the flags is any
+// combination of the MappedModuleFlags enumeration.
+//
+// The returned buffer must be freed with a placement delete from the ntdll
+// level allocator:
+//
+// UNICODE_STRING* name = GetPEImageInfoFromModule(HMODULE module, &flags);
+// if (!name) {
+// // probably not a valid dll
+// return;
+// }
+// InsertYourLogicHere(name);
+// operator delete(name, NT_ALLOC);
+UNICODE_STRING* GetImageInfoFromModule(HMODULE module, uint32_t* flags);
+
+// Returns the name and characteristics for a given PE module. The return
+// value is the name as defined by the export table.
+//
+// The returned buffer is within the PE module and must not be freed.
+const char* GetAnsiImageInfoFromModule(HMODULE module);
+
+// Returns the full path and filename for a given dll.
+// May return nullptr if the provided address is not backed by a named section,
+// or if the current OS version doesn't support the call. The returned buffer
+// must be freed with a placement delete (see GetImageNameFromModule example).
+UNICODE_STRING* GetBackingFilePath(PVOID address);
+
+// Returns the last component of a path that contains the module name.
+// It will return nullptr if the path ends with the path separator. The returned
+// buffer must be freed with a placement delete (see GetImageNameFromModule
+// example).
+UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path);
+
+// Returns true if the parameters correspond to a dll mapped as code.
+bool IsValidImageSection(HANDLE section,
+ PVOID* base,
+ PLARGE_INTEGER offset,
+ PSIZE_T view_size);
+
+// Converts an ansi string to an UNICODE_STRING.
+UNICODE_STRING* AnsiToUnicode(const char* string);
+
+// Resolves a handle to an nt path. Returns true if the handle can be resolved.
+bool NtGetPathFromHandle(HANDLE handle,
+ std::unique_ptr<wchar_t, NtAllocDeleter>* path);
+
+// Provides a simple way to temporarily change the protection of a memory page.
+class AutoProtectMemory {
+ public:
+ AutoProtectMemory()
+ : changed_(false), address_(nullptr), bytes_(0), old_protect_(0) {}
+
+ ~AutoProtectMemory() { RevertProtection(); }
+
+ // Sets the desired protection of a given memory range.
+ NTSTATUS ChangeProtection(void* address, size_t bytes, ULONG protect);
+
+ // Restores the original page protection.
+ NTSTATUS RevertProtection();
+
+ private:
+ bool changed_;
+ void* address_;
+ size_t bytes_;
+ ULONG old_protect_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutoProtectMemory);
+};
+
+// Returns true if the file_rename_information structure is supported by our
+// rename handler.
+bool IsSupportedRenameCall(FILE_RENAME_INFORMATION* file_info,
+ DWORD length,
+ uint32_t file_info_class);
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_SANDBOX_NT_UTIL_H__