Commit 6864777a authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Verify free block contents when validating the heap.

parent c0abf594
...@@ -1005,6 +1005,8 @@ static BOOL HEAP_IsValidArenaPtr( const HEAP *heap, const ARENA_FREE *ptr ) ...@@ -1005,6 +1005,8 @@ static BOOL HEAP_IsValidArenaPtr( const HEAP *heap, const ARENA_FREE *ptr )
*/ */
static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena ) static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
{ {
DWORD flags = subheap->heap->flags;
SIZE_T size;
ARENA_FREE *prev, *next; ARENA_FREE *prev, *next;
char *heapEnd = (char *)subheap->base + subheap->size; char *heapEnd = (char *)subheap->base + subheap->size;
...@@ -1030,10 +1032,10 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena ) ...@@ -1030,10 +1032,10 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
return FALSE; return FALSE;
} }
/* Check arena size */ /* Check arena size */
if ((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) > heapEnd) size = pArena->size & ARENA_SIZE_MASK;
if ((char *)(pArena + 1) + size > heapEnd)
{ {
ERR("Heap %p: bad size %08x for free arena %p\n", ERR("Heap %p: bad size %08lx for free arena %p\n", subheap->heap, size, pArena );
subheap->heap, pArena->size & ARENA_SIZE_MASK, pArena );
return FALSE; return FALSE;
} }
/* Check that next pointer is valid */ /* Check that next pointer is valid */
...@@ -1069,25 +1071,40 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena ) ...@@ -1069,25 +1071,40 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
return FALSE; return FALSE;
} }
/* Check that next block has PREV_FREE flag */ /* Check that next block has PREV_FREE flag */
if ((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) < heapEnd) if ((char *)(pArena + 1) + size < heapEnd)
{ {
if (!(*(DWORD *)((char *)(pArena + 1) + if (!(*(DWORD *)((char *)(pArena + 1) + size) & ARENA_FLAG_PREV_FREE))
(pArena->size & ARENA_SIZE_MASK)) & ARENA_FLAG_PREV_FREE))
{ {
ERR("Heap %p: free arena %p next block has no PREV_FREE flag\n", ERR("Heap %p: free arena %p next block has no PREV_FREE flag\n",
subheap->heap, pArena ); subheap->heap, pArena );
return FALSE; return FALSE;
} }
/* Check next block back pointer */ /* Check next block back pointer */
if (*((ARENA_FREE **)((char *)(pArena + 1) + if (*((ARENA_FREE **)((char *)(pArena + 1) + size) - 1) != pArena)
(pArena->size & ARENA_SIZE_MASK)) - 1) != pArena)
{ {
ERR("Heap %p: arena %p has wrong back ptr %p\n", ERR("Heap %p: arena %p has wrong back ptr %p\n",
subheap->heap, pArena, subheap->heap, pArena,
*((ARENA_FREE **)((char *)(pArena+1) + (pArena->size & ARENA_SIZE_MASK)) - 1)); *((ARENA_FREE **)((char *)(pArena+1) + size) - 1));
return FALSE; return FALSE;
} }
} }
if (flags & HEAP_FREE_CHECKING_ENABLED)
{
DWORD *ptr = (DWORD *)(pArena + 1);
char *end = (char *)(pArena + 1) + size;
if (end >= heapEnd) end = (char *)subheap->base + subheap->commitSize;
while (ptr < (DWORD *)end - 1)
{
if (*ptr != ARENA_FREE_FILLER)
{
ERR("Heap %p: free block %p overwritten at %p by %08x\n",
subheap->heap, (ARENA_INUSE *)pArena + 1, ptr, *ptr );
return FALSE;
}
ptr++;
}
}
return TRUE; return TRUE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment