Alexandre Julliard : ntdll: Verify free block contents when validating the heap.
Alexandre Julliard
julliard at winehq.org
Tue Jan 26 11:21:09 CST 2010
Module: wine
Branch: master
Commit: 6864777a107268ad1f05ebbe408be8dd38e7219e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6864777a107268ad1f05ebbe408be8dd38e7219e
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Jan 26 14:35:08 2010 +0100
ntdll: Verify free block contents when validating the heap.
---
dlls/ntdll/heap.c | 35 ++++++++++++++++++++++++++---------
1 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 9a80116..72a0069 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -1005,6 +1005,8 @@ static BOOL HEAP_IsValidArenaPtr( const HEAP *heap, const ARENA_FREE *ptr )
*/
static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
{
+ DWORD flags = subheap->heap->flags;
+ SIZE_T size;
ARENA_FREE *prev, *next;
char *heapEnd = (char *)subheap->base + subheap->size;
@@ -1030,10 +1032,10 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
return FALSE;
}
/* 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",
- subheap->heap, pArena->size & ARENA_SIZE_MASK, pArena );
+ ERR("Heap %p: bad size %08lx for free arena %p\n", subheap->heap, size, pArena );
return FALSE;
}
/* Check that next pointer is valid */
@@ -1069,25 +1071,40 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
return FALSE;
}
/* 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) +
- (pArena->size & ARENA_SIZE_MASK)) & ARENA_FLAG_PREV_FREE))
+ if (!(*(DWORD *)((char *)(pArena + 1) + size) & ARENA_FLAG_PREV_FREE))
{
ERR("Heap %p: free arena %p next block has no PREV_FREE flag\n",
subheap->heap, pArena );
return FALSE;
}
/* Check next block back pointer */
- if (*((ARENA_FREE **)((char *)(pArena + 1) +
- (pArena->size & ARENA_SIZE_MASK)) - 1) != pArena)
+ if (*((ARENA_FREE **)((char *)(pArena + 1) + size) - 1) != pArena)
{
ERR("Heap %p: arena %p has wrong back ptr %p\n",
subheap->heap, pArena,
- *((ARENA_FREE **)((char *)(pArena+1) + (pArena->size & ARENA_SIZE_MASK)) - 1));
+ *((ARENA_FREE **)((char *)(pArena+1) + size) - 1));
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;
}
More information about the wine-cvs
mailing list