Rémi Bernon : ntdll: Remove tail checking on large blocks.

Alexandre Julliard julliard at winehq.org
Tue May 31 15:57:59 CDT 2022


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

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Mon May 30 22:07:42 2022 +0200

ntdll: Remove tail checking on large blocks.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>

---

 dlls/kernel32/tests/heap.c | 27 +++------------------------
 dlls/ntdll/heap.c          | 30 +++++++++---------------------
 2 files changed, 12 insertions(+), 45 deletions(-)

diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 8ef0bfc3668..bb5e57fe94e 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -2242,7 +2242,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags
         ok( diff > expect_size, "got diff %#Ix\n", diff );
 
         tail = ptr0[alloc_size] | ptr1[alloc_size] | ptr2[alloc_size];
-        todo_wine_if( heap_flags & HEAP_TAIL_CHECKING_ENABLED )
         ok( !tail, "got tail\n" );
 
         ret = HeapFree( heap, 0, ptr2 );
@@ -2492,29 +2491,9 @@ static void test_heap_checks( DWORD flags )
     if (flags & HEAP_TAIL_CHECKING_ENABLED)
     {
         /* Windows doesn't do tail checking on large blocks */
-        ok( p[large_size] == 0xab || broken(p[large_size] == 0), "wrong data %x\n", p[large_size] );
-        ok( p[large_size+1] == 0xab || broken(p[large_size+1] == 0), "wrong data %x\n", p[large_size+1] );
-        ok( p[large_size+2] == 0xab || broken(p[large_size+2] == 0), "wrong data %x\n", p[large_size+2] );
-        if (p[large_size] == 0xab)
-        {
-            p[large_size] = 0xcc;
-            ret = HeapValidate( GetProcessHeap(), 0, p );
-            ok( !ret, "HeapValidate succeeded\n" );
-
-            /* other calls only check when HEAP_VALIDATE is set */
-            if (flags & HEAP_VALIDATE)
-            {
-                size = HeapSize( GetProcessHeap(), 0, p );
-                ok( size == ~(SIZE_T)0, "Wrong size %Iu\n", size );
-
-                p2 = HeapReAlloc( GetProcessHeap(), 0, p, large_size - 3 );
-                ok( p2 == NULL, "HeapReAlloc succeeded\n" );
-
-                ret = HeapFree( GetProcessHeap(), 0, p );
-                ok( !ret, "HeapFree succeeded\n" );
-            }
-            p[large_size] = 0xab;
-        }
+        ok( p[large_size] == 0, "wrong data %x\n", p[large_size] );
+        ok( p[large_size + 1] == 0, "wrong data %x\n", p[large_size + 1] );
+        ok( p[large_size + 2] == 0, "wrong data %x\n", p[large_size + 2] );
     }
 
     ret = HeapFree( GetProcessHeap(), 0, p );
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 0102ba3ea42..00b4cd7e894 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -783,7 +783,7 @@ static inline void shrink_used_block( SUBHEAP *subheap, struct block *block, UIN
 static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size )
 {
     ARENA_LARGE *arena;
-    SIZE_T block_size = sizeof(*arena) + ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags);
+    SIZE_T block_size = sizeof(*arena) + ROUND_SIZE( size );
     LPVOID address = NULL;
 
     if (!(flags & HEAP_GROWABLE)) return NULL;
@@ -799,8 +799,9 @@ static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size )
     arena->block_size = block_size;
     arena->size = ARENA_LARGE_SIZE;
     arena->magic = ARENA_LARGE_MAGIC;
-    mark_block_tail( (char *)(arena + 1) + size, block_size - sizeof(*arena) - size, flags );
     list_add_tail( &heap->large_list, &arena->entry );
+    valgrind_make_noaccess( (char *)arena + sizeof(*arena) + arena->data_size,
+                            arena->block_size - sizeof(*arena) - arena->data_size );
     return arena + 1;
 }
 
@@ -825,19 +826,17 @@ static void free_large_block( HEAP *heap, void *ptr )
 static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T size )
 {
     ARENA_LARGE *arena = (ARENA_LARGE *)ptr - 1;
+    SIZE_T old_size = arena->data_size;
     void *new_ptr;
 
     if (arena->block_size - sizeof(*arena) >= size)
     {
-        SIZE_T unused = arena->block_size - sizeof(*arena) - size;
-
         /* FIXME: we could remap zero-pages instead */
-        valgrind_notify_resize( arena + 1, arena->data_size, size );
-        if (size > arena->data_size)
-            initialize_block( (char *)ptr + arena->data_size, size - arena->data_size, unused, flags );
-        else
-            mark_block_tail( (char *)ptr + size, unused, flags );
+        valgrind_notify_resize( arena + 1, old_size, size );
+        if (size > old_size) initialize_block( (char *)ptr + old_size, size - old_size, 0, flags );
         arena->data_size = size;
+        valgrind_make_noaccess( (char *)arena + sizeof(*arena) + arena->data_size,
+                                arena->block_size - sizeof(*arena) - arena->data_size );
         return ptr;
     }
     if (flags & HEAP_REALLOC_IN_PLACE_ONLY) return NULL;
@@ -847,7 +846,7 @@ static void *realloc_large_block( HEAP *heap, DWORD flags, void *ptr, SIZE_T siz
         return NULL;
     }
     valgrind_notify_alloc( new_ptr, size, 0 );
-    memcpy( new_ptr, ptr, arena->data_size );
+    memcpy( new_ptr, ptr, old_size );
     valgrind_notify_free( ptr );
     free_large_block( heap, ptr );
     return new_ptr;
@@ -877,12 +876,6 @@ static BOOL validate_large_arena( const HEAP *heap, const ARENA_LARGE *arena )
         err = "invalid block header";
     else if (!contains( arena, arena->block_size, arena + 1, arena->data_size ))
         err = "invalid block size";
-    else if (heap->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 && !err; i++) if (data[i] != ARENA_TAIL_FILLER) err = "invalid block tail";
-    }
 
     if (err)
     {
@@ -1317,7 +1310,6 @@ static void heap_set_debug_flags( HANDLE handle )
     if (flags & (HEAP_FREE_CHECKING_ENABLED | HEAP_TAIL_CHECKING_ENABLED))  /* fix existing blocks */
     {
         struct block *block;
-        ARENA_LARGE *large;
         SUBHEAP *subheap;
 
         LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry )
@@ -1342,10 +1334,6 @@ static void heap_set_debug_flags( HANDLE handle )
                 }
             }
         }
-
-        LIST_FOR_EACH_ENTRY( large, &heap->large_list, ARENA_LARGE, entry )
-            mark_block_tail( (char *)(large + 1) + large->data_size,
-                             large->block_size - sizeof(*large) - large->data_size, flags );
     }
 
     if ((heap->flags & HEAP_GROWABLE) && !heap->pending_free &&




More information about the wine-cvs mailing list