linux: Fix _aligned_realloc implementation

Out-of-bounds memory is no longer accessed if the realloc size is larger.
If reallocation fails, the old memory will not be freed and a memcpy
will not take place.

This should match the Windows _aligned_realloc behaviour, except that an
extra parameter is used.
This commit is contained in:
Jonathan Li 2015-09-13 18:02:07 +01:00
parent 4760d71a86
commit 67dc65ea91
4 changed files with 12 additions and 11 deletions

View File

@ -15,7 +15,6 @@
#pragma once
#include "MemcpyFast.h"
#include "SafeArray.h"
// Internal constructor for use by derived classes. This allows a derived class to
@ -132,7 +131,7 @@ T* SafeAlignedArray<T,Alignment>::_virtual_realloc( int newsize )
{
return (T*)( ( this->m_ptr == NULL ) ?
_aligned_malloc( newsize * sizeof(T), Alignment ) :
_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment )
pcsx2_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment, this->m_size * sizeof(T) )
);
}

View File

@ -51,8 +51,11 @@
// aligned_malloc: Implement/declare linux equivalents here!
#if !defined(_MSC_VER)
extern void* __fastcall _aligned_malloc(size_t size, size_t align);
extern void* __fastcall _aligned_realloc(void* handle, size_t size, size_t align);
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t new_size, size_t align, size_t old_size);
extern void _aligned_free(void* pmem);
#else
#define pcsx2_aligned_realloc(handle, new_size, align, old_size) \
_aligned_realloc(handle, new_size, align)
#endif
// --------------------------------------------------------------------------------------
@ -245,8 +248,8 @@ public:
virtual void Resize( size_t newsize )
{
this->m_buffer = (T*)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T));
this->m_size = newsize;
this->m_buffer = (T*)_aligned_realloc(this->m_buffer, newsize * sizeof(T), align);
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");

View File

@ -30,15 +30,14 @@ void* __fastcall _aligned_malloc(size_t size, size_t align)
#endif
}
void* __fastcall _aligned_realloc(void* handle, size_t size, size_t align)
void* __fastcall pcsx2_aligned_realloc(void* handle, size_t new_size, size_t align, size_t old_size)
{
pxAssert( align < 0x10000 );
void* newbuf = _aligned_malloc( size, align );
void* newbuf = _aligned_malloc(new_size, align);
if( handle != NULL )
{
memcpy( newbuf, handle, size );
if (newbuf != NULL && handle != NULL) {
memcpy(newbuf, handle, std::min(old_size, new_size));
_aligned_free(handle);
}
return newbuf;

View File

@ -81,7 +81,7 @@ public:
u32 d = (u32&)dataPtr;
SizeChain<T>& bucket( mBucket[d % hSize] );
if( bucket.Chain = (T*)_aligned_realloc( bucket.Chain, sizeof(T)*(bucket.Size+1), 16), bucket.Chain==NULL ) {
if( (bucket.Chain = (T*)pcsx2_aligned_realloc( bucket.Chain, sizeof(T)*(bucket.Size+1), 16, sizeof(T)*bucket.Size)) == NULL ) {
throw Exception::OutOfMemory(
wxsFormat(L"HashBucket Chain (bucket size=%d)", bucket.Size+1)
);