util-memory: Use standard alloc/free and fix incorrect aligned length

The custom allocator occasionally returned memory that was aligned, but did not have enough space to store the actual size due to a calculation error in the size. This resulted in situations where allocating 1022 bytes would give you a writable buffer of only 1020 bytes or less, or also known as writing into unknown memory, possibly even the heap. This is now fixed by doubling the padding used.

Additionally it will now default to using standard allocators, which should work better and rely on the Compiler.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2018-02-24 04:35:49 +01:00
parent eccd95c68c
commit 01bf510a28

View file

@ -19,25 +19,50 @@
#include "util-memory.h"
#include <cstdlib>
#define USE_STD_ALLOC_FREE
void* util::malloc_aligned(size_t align, size_t size) {
#ifdef USE_STD_ALLOC_FREE
#if defined(_MSC_VER)
#ifdef DEBUG
return _aligned_malloc_dbg(size, align);
#else
return _aligned_malloc(size, align);
#endif
#else
return aligned_malloc(align, size);
#endif
#else
// Ensure that we have space for the pointer and the data.
size_t asize = aligned_offset(align, size + sizeof(void*));
size_t asize = aligned_offset(align, size + (sizeof(void*) * 2));
// Allocate memory and store integer representation of pointer.
void* ptr = malloc(asize);
// Calculate actual aligned position
intptr_t ptr_off = aligned_offset(align, reinterpret_cast<size_t>(ptr)+sizeof(void*));
intptr_t ptr_off = aligned_offset(align, reinterpret_cast<size_t>(ptr) + sizeof(void*));
// Store actual pointer at ptr_off - sizeof(void*).
*reinterpret_cast<intptr_t*>(ptr_off - sizeof(void*)) = reinterpret_cast<intptr_t>(ptr);
// Return aligned pointer
return reinterpret_cast<void*>(ptr_off);
#endif
}
void util::free_aligned(void* mem) {
void* ptr = reinterpret_cast<void*>(*reinterpret_cast<intptr_t*>(static_cast<char*>(mem)-sizeof(void*)));
#ifdef USE_STD_ALLOC_FREE
#if defined(_MSC_VER)
#ifdef DEBUG
_aligned_free_dbg(mem);
#else
_aligned_free(mem);
#endif
#else
free(mem);
#endif
#else
void* ptr = reinterpret_cast<void*>(*reinterpret_cast<intptr_t*>(static_cast<char*>(mem) - sizeof(void*)));
free(ptr);
#endif
}