From: Jinoh Kang jinoh.kang.kr@gmail.com
--- dlls/ntdll/heap.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 523344fe0f5..c8eec050b1a 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -338,8 +338,10 @@ static inline struct block *next_block( const SUBHEAP *subheap, const struct blo return (struct block *)next; }
-static inline BOOL check_subheap( const SUBHEAP *subheap ) +static inline BOOL check_subheap( const SUBHEAP *subheap, const struct heap *heap ) { + if (subheap->user_value != heap) return FALSE; + return contains( &subheap->block, subheap->block_size, subheap + 1, subheap->data_size ); }
@@ -447,13 +449,13 @@ static inline void valgrind_notify_resize( void const *ptr, SIZE_T size_old, SIZ #endif }
-static void valgrind_notify_free_all( SUBHEAP *subheap ) +static void valgrind_notify_free_all( SUBHEAP *subheap, const struct heap *heap ) { #ifdef VALGRIND_FREELIKE_BLOCK struct block *block;
if (!RUNNING_ON_VALGRIND) return; - if (!check_subheap( subheap )) return; + if (!check_subheap( subheap, heap )) return;
for (block = first_block( subheap ); block; block = next_block( subheap, block )) { @@ -549,7 +551,7 @@ static void heap_dump( const struct 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; + if (!check_subheap( subheap, heap )) return;
overhead += subheap_overhead( subheap ); for (block = first_block( subheap ); block; block = next_block( subheap, block )) @@ -648,7 +650,7 @@ static SUBHEAP *find_subheap( const struct heap *heap, const struct block *block LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry ) { SIZE_T blocks_size = (char *)last_block( subheap ) - (char *)first_block( subheap ); - if (!check_subheap( subheap )) return NULL; + if (!check_subheap( subheap, heap )) return NULL; if (contains( first_block( subheap ), blocks_size, block, sizeof(*block) )) return subheap; /* outside of blocks region, possible corruption or heap_walk */ if (contains( subheap_base( subheap ), subheap_size( subheap ), block, 0 )) return heap_walk ? subheap : NULL; @@ -1152,9 +1154,9 @@ static BOOL heap_validate( const struct heap *heap )
LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry ) { - if (!check_subheap( subheap )) + if (!check_subheap( subheap, heap )) { - ERR( "heap %p, subheap %p corrupted sizes\n", heap, subheap ); + ERR( "heap %p, subheap %p corrupted sizes or user_value\n", heap, subheap ); if (TRACE_ON(heap)) heap_dump( heap ); return FALSE; } @@ -1271,7 +1273,7 @@ static void heap_set_debug_flags( HANDLE handle ) { const char *commit_end = subheap_commit_end( subheap );
- if (!check_subheap( subheap )) break; + if (!check_subheap( subheap, heap )) break;
for (block = first_block( subheap ); block; block = next_block( subheap, block )) { @@ -1467,13 +1469,13 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE handle ) LIST_FOR_EACH_ENTRY_SAFE( subheap, next, &heap->subheap_list, SUBHEAP, entry ) { if (subheap == &heap->subheap) continue; /* do this one last */ - valgrind_notify_free_all( subheap ); + valgrind_notify_free_all( subheap, heap ); list_remove( &subheap->entry ); size = 0; addr = ROUND_ADDR( subheap, REGION_ALIGN - 1 ); NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); } - valgrind_notify_free_all( &heap->subheap ); + valgrind_notify_free_all( &heap->subheap, heap ); size = 0; addr = heap; NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );