Module: wine Branch: master Commit: b887e31d151be53324bc0670f01ebc5ee6349dac URL: https://gitlab.winehq.org/wine/wine/-/commit/b887e31d151be53324bc0670f01ebc5...
Author: Jinoh Kang jinoh.kang.kr@gmail.com Date: Sat Dec 31 22:55:12 2022 +0900
ntdll: Check for delayed free block in heap_validate_ptr.
Today, the heap does not catch double free when both HEAP_VALIDATE and HEAP_FREE_CHECKING_ENABLED are on, since validate_used_block() accepts BLOCK_TYPE_DEAD as a valid (allocated) block type.
Fix this by adding an explicit check that rejects BLOCK_TYPE_DEAD in heap_validate_ptr.
---
dlls/ntdll/heap.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index aafbbd0f523..523344fe0f5 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1067,7 +1067,8 @@ static BOOL validate_free_block( const struct heap *heap, const SUBHEAP *subheap }
-static BOOL validate_used_block( const struct heap *heap, const SUBHEAP *subheap, const struct block *block ) +static BOOL validate_used_block( const struct heap *heap, const SUBHEAP *subheap, const struct block *block, + unsigned int expected_block_type ) { const char *err = NULL, *base = subheap_base( subheap ), *commit_end = subheap_commit_end( subheap ); DWORD flags = heap->flags; @@ -1078,6 +1079,8 @@ static BOOL validate_used_block( const struct heap *heap, const SUBHEAP *subheap err = "invalid block BLOCK_ALIGN"; else if (block_get_type( block ) != BLOCK_TYPE_USED && block_get_type( block ) != BLOCK_TYPE_DEAD) err = "invalid block header"; + else if (expected_block_type && block_get_type( block ) != expected_block_type) + err = "invalid block type"; else if (block_get_flags( block ) & BLOCK_FLAG_FREE) err = "invalid block flags"; else if (!contains( base, commit_end - base, block, block_get_size( block ) )) @@ -1138,7 +1141,7 @@ static BOOL heap_validate_ptr( const struct heap *heap, const void *ptr ) return validate_large_block( heap, block ); }
- return validate_used_block( heap, subheap, block ); + return validate_used_block( heap, subheap, block, BLOCK_TYPE_USED ); }
static BOOL heap_validate( const struct heap *heap ) @@ -1164,7 +1167,7 @@ static BOOL heap_validate( const struct heap *heap ) } else { - if (!validate_used_block( heap, subheap, block )) return FALSE; + if (!validate_used_block( heap, subheap, block, 0 )) return FALSE; } } }