Alexandre Julliard : ntdll: Verify the tail contents when validating a large block.

Alexandre Julliard julliard at winehq.org
Tue Jan 26 11:21:10 CST 2010


Module: wine
Branch: master
Commit: bf975d1f85fad29588cf7979f1d40c11bc49bb2c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bf975d1f85fad29588cf7979f1d40c11bc49bb2c

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jan 26 16:08:22 2010 +0100

ntdll: Verify the tail contents when validating a large block.

---

 dlls/ntdll/heap.c |   33 +++++++++++++++++++++++++++++++--
 1 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 7cbc8ef..2e0dcc6 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -764,6 +764,8 @@ static ARENA_LARGE *find_large_block( HEAP *heap, const void *ptr )
  */
 static BOOL validate_large_arena( HEAP *heap, const ARENA_LARGE *arena, BOOL quiet )
 {
+    DWORD flags = heap->flags;
+
     if ((ULONG_PTR)arena % getpagesize())
     {
         if (quiet == NOISY)
@@ -794,6 +796,25 @@ static BOOL validate_large_arena( HEAP *heap, const ARENA_LARGE *arena, BOOL qui
         }
         return FALSE;
     }
+    if (arena->data_size > arena->block_size - sizeof(*arena))
+    {
+        ERR( "Heap %p: invalid large arena %p size %lx/%lx\n",
+             heap, arena, arena->data_size, arena->block_size );
+        return FALSE;
+    }
+    if (flags & HEAP_TAIL_CHECKING_ENABLED)
+    {
+        SIZE_T i, unused = arena->block_size - sizeof(*arena) - arena->data_size;
+        const unsigned char *data = (const unsigned char *)(arena + 1) + arena->data_size;
+
+        for (i = 0; i < unused; i++)
+        {
+            if (data[i] == ARENA_TAIL_FILLER) continue;
+            ERR("Heap %p: block %p tail overwritten at %p (byte %lu/%lu == 0x%02x)\n",
+                heap, arena + 1, data + i, i, unused, data[i] );
+            return FALSE;
+        }
+    }
     return TRUE;
 }
 
@@ -1614,7 +1635,11 @@ BOOLEAN WINAPI RtlFreeHeap( HANDLE heap, ULONG flags, PVOID ptr )
     pInUse  = (ARENA_INUSE *)ptr - 1;
     if (!(subheap = HEAP_FindSubHeap( heapPtr, pInUse )))
     {
-        if (!find_large_block( heapPtr, ptr )) goto error;
+        ARENA_LARGE *large_arena = find_large_block( heapPtr, ptr );
+
+        if (!large_arena) goto error;
+        if ((heapPtr->flags & HEAP_VALIDATE) && !validate_large_arena( heapPtr, large_arena, QUIET ))
+            goto error;
         free_large_block( heapPtr, flags, ptr );
         goto done;
     }
@@ -1682,7 +1707,11 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
     pArena = (ARENA_INUSE *)ptr - 1;
     if (!(subheap = HEAP_FindSubHeap( heapPtr, pArena )))
     {
-        if (!find_large_block( heapPtr, ptr )) goto error;
+        ARENA_LARGE *large_arena = find_large_block( heapPtr, ptr );
+
+        if (!large_arena) goto error;
+        if ((heapPtr->flags & HEAP_VALIDATE) && !validate_large_arena( heapPtr, large_arena, QUIET ))
+            goto error;
         if (!(ret = realloc_large_block( heapPtr, flags, ptr, size ))) goto oom;
         notify_free( ptr );
         goto done;




More information about the wine-cvs mailing list