kernel: Avoid heap corruption on invalid parameter in GlobalFree().
This commit is contained in:
parent
13c2f4742f
commit
dcbfa1179d
|
@ -683,13 +683,19 @@ HGLOBAL WINAPI GlobalReAlloc(
|
||||||
*
|
*
|
||||||
* Free a global memory object.
|
* Free a global memory object.
|
||||||
*
|
*
|
||||||
|
* PARAMS
|
||||||
|
* hmem [I] Handle of the global memory object
|
||||||
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* NULL: Success
|
* Success: NULL
|
||||||
* Handle: Failure
|
* Failure: The provided handle
|
||||||
|
*
|
||||||
|
* NOTES
|
||||||
|
* When the handle is invalid, last error is set to ERROR_INVALID_HANDLE
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
HGLOBAL WINAPI GlobalFree(
|
HGLOBAL WINAPI GlobalFree(HGLOBAL hmem)
|
||||||
HGLOBAL hmem /* [in] Handle of global memory object */
|
{
|
||||||
) {
|
|
||||||
PGLOBAL32_INTERN pintern;
|
PGLOBAL32_INTERN pintern;
|
||||||
HGLOBAL hreturned;
|
HGLOBAL hreturned;
|
||||||
|
|
||||||
|
@ -707,6 +713,7 @@ HGLOBAL WINAPI GlobalFree(
|
||||||
|
|
||||||
if(pintern->Magic==MAGIC_GLOBAL_USED)
|
if(pintern->Magic==MAGIC_GLOBAL_USED)
|
||||||
{
|
{
|
||||||
|
pintern->Magic = 0xdead;
|
||||||
|
|
||||||
/* WIN98 does not make this test. That is you can free a */
|
/* WIN98 does not make this test. That is you can free a */
|
||||||
/* block you have not unlocked. Go figure!! */
|
/* block you have not unlocked. Go figure!! */
|
||||||
|
@ -719,6 +726,12 @@ HGLOBAL WINAPI GlobalFree(
|
||||||
if(!HeapFree(GetProcessHeap(), 0, pintern))
|
if(!HeapFree(GetProcessHeap(), 0, pintern))
|
||||||
hreturned=hmem;
|
hreturned=hmem;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN("invalid handle %p (Magic: 0x%04x)\n", hmem, pintern->Magic);
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
hreturned = hmem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__EXCEPT_PAGE_FAULT
|
__EXCEPT_PAGE_FAULT
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
#define MAGIC_DEAD 0xdeadbeef
|
||||||
|
|
||||||
static SIZE_T resize_9x(SIZE_T size)
|
static SIZE_T resize_9x(SIZE_T size)
|
||||||
{
|
{
|
||||||
DWORD dwSizeAligned = (size + 3) & ~3;
|
DWORD dwSizeAligned = (size + 3) & ~3;
|
||||||
|
@ -35,6 +37,7 @@ START_TEST(heap)
|
||||||
{
|
{
|
||||||
void *mem;
|
void *mem;
|
||||||
HGLOBAL gbl;
|
HGLOBAL gbl;
|
||||||
|
HGLOBAL hsecond;
|
||||||
SIZE_T size;
|
SIZE_T size;
|
||||||
|
|
||||||
/* Heap*() functions */
|
/* Heap*() functions */
|
||||||
|
@ -75,6 +78,15 @@ START_TEST(heap)
|
||||||
gbl = GlobalReAlloc(0, 10, GMEM_MOVEABLE);
|
gbl = GlobalReAlloc(0, 10, GMEM_MOVEABLE);
|
||||||
ok(gbl == NULL, "global realloc allocated memory\n");
|
ok(gbl == NULL, "global realloc allocated memory\n");
|
||||||
|
|
||||||
|
/* invalid handles are catched in windows */
|
||||||
|
gbl = GlobalAlloc(GMEM_MOVEABLE, 256);
|
||||||
|
GlobalFree(gbl);
|
||||||
|
SetLastError(MAGIC_DEAD);
|
||||||
|
hsecond = GlobalFree(gbl); /* invalid handle: free memory twice */
|
||||||
|
ok( (hsecond == gbl) && (GetLastError() == ERROR_INVALID_HANDLE),
|
||||||
|
"returned %p with 0x%08lx (expected %p with ERROR_INVALID_HANDLE)\n",
|
||||||
|
hsecond, GetLastError(), gbl);
|
||||||
|
|
||||||
/* Local*() functions */
|
/* Local*() functions */
|
||||||
gbl = LocalAlloc(LMEM_MOVEABLE, 0);
|
gbl = LocalAlloc(LMEM_MOVEABLE, 0);
|
||||||
ok(gbl != NULL, "local memory not allocated for size 0\n");
|
ok(gbl != NULL, "local memory not allocated for size 0\n");
|
||||||
|
@ -96,6 +108,15 @@ START_TEST(heap)
|
||||||
gbl = LocalReAlloc(0, 10, LMEM_MOVEABLE);
|
gbl = LocalReAlloc(0, 10, LMEM_MOVEABLE);
|
||||||
ok(gbl == NULL, "local realloc allocated memory\n");
|
ok(gbl == NULL, "local realloc allocated memory\n");
|
||||||
|
|
||||||
|
/* invalid handles are catched in windows */
|
||||||
|
gbl = LocalAlloc(GMEM_MOVEABLE, 256);
|
||||||
|
LocalFree(gbl);
|
||||||
|
SetLastError(MAGIC_DEAD);
|
||||||
|
hsecond = LocalFree(gbl); /* invalid handle: free memory twice */
|
||||||
|
ok( (hsecond == gbl) && (GetLastError() == ERROR_INVALID_HANDLE),
|
||||||
|
"returned %p with 0x%08lx (expected %p with ERROR_INVALID_HANDLE)\n",
|
||||||
|
hsecond, GetLastError(), gbl);
|
||||||
|
|
||||||
/* trying to lock empty memory should give an error */
|
/* trying to lock empty memory should give an error */
|
||||||
gbl = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,0);
|
gbl = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,0);
|
||||||
ok(gbl != NULL, "returned NULL\n");
|
ok(gbl != NULL, "returned NULL\n");
|
||||||
|
|
Loading…
Reference in New Issue