Rémi Bernon : ntdll: Check subheap sizes for consistency before using them.

Alexandre Julliard julliard at winehq.org
Fri May 13 15:45:13 CDT 2022


Module: wine
Branch: master
Commit: 1196b46b293291b455345a06a61b8687d6911b68
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1196b46b293291b455345a06a61b8687d6911b68

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Wed May  4 20:19:50 2022 +0200

ntdll: Check subheap sizes for consistency before using them.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/heap.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index ab9985a1016..a917abe39af 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -250,6 +250,12 @@ static inline struct block *next_block( const SUBHEAP *subheap, const struct blo
     return (struct block *)next;
 }
 
+static inline BOOL check_subheap( const SUBHEAP *subheap )
+{
+    const char *base = subheap->base;
+    return contains( base, subheap->size, base + subheap->headerSize, subheap->commitSize - subheap->headerSize );
+}
+
 static BOOL heap_validate( HEAP *heap, BOOL quiet );
 
 /* mark a block of memory as free for debugging purposes */
@@ -353,6 +359,7 @@ static void subheap_notify_free_all(SUBHEAP const *subheap)
     char const *ptr = (char const *)subheap->base + subheap->headerSize;
 
     if (!RUNNING_ON_VALGRIND) return;
+    if (!check_subheap( subheap )) return;
 
     while (ptr < (char const *)subheap->base + subheap->size)
     {
@@ -454,6 +461,8 @@ static void heap_dump( const HEAP *heap )
         TRACE( "    %p: base %p first %p last %p end %p\n", subheap, base, first_block( subheap ),
                last_block( subheap ), base + subheap_size( subheap ) );
 
+        if (!check_subheap( subheap )) return;
+
         overhead += (char *)first_block( subheap ) - base;
         for (block = first_block( subheap ); block; block = next_block( subheap, block ))
         {
@@ -614,6 +623,7 @@ static SUBHEAP *find_subheap( const HEAP *heap, const void *ptr )
 
     LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry )
     {
+        if (!check_subheap( subheap )) return NULL;
         if (contains( subheap_base( subheap ), subheap_size( subheap ), ptr, sizeof(struct block) ))
             return subheap;
     }
@@ -1456,6 +1466,14 @@ static BOOL heap_validate( HEAP *heap, BOOL quiet )
     LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry )
     {
         char *ptr = (char *)subheap->base + subheap->headerSize;
+
+        if (!check_subheap( subheap ))
+        {
+            ERR( "heap %p, subheap %p corrupted sizes\n", heap, subheap );
+            if (TRACE_ON(heap)) heap_dump( heap );
+            return FALSE;
+        }
+
         while (ptr < (char *)subheap->base + subheap->size)
         {
             if (*(DWORD *)ptr & ARENA_FLAG_FREE)
@@ -1577,6 +1595,9 @@ static void heap_set_debug_flags( HANDLE handle )
         {
             char *ptr = (char *)subheap->base + subheap->headerSize;
             char *end = (char *)subheap->base + subheap->commitSize;
+
+            if (!check_subheap( subheap )) break;
+
             while (ptr < end)
             {
                 ARENA_INUSE *arena = (ARENA_INUSE *)ptr;




More information about the wine-cvs mailing list