diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 81850fef6a3..0c0de113cde 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -488,7 +488,7 @@ static void test_heap_checks( DWORD flags ) { BYTE old, *p, *p2; BOOL ret; - SIZE_T size, large_size = 800 * 1024 + 37; + SIZE_T i, size, large_size = 800 * 1024 + 37; if (flags & HEAP_PAGE_ALLOCS) return; /* no tests for that case yet */ trace( "testing heap flags %08x\n", flags ); @@ -640,6 +640,18 @@ static void test_heap_checks( DWORD flags ) ret = HeapFree( GetProcessHeap(), 0, p ); ok( ret, "HeapFree failed\n" ); + + /* test block sizes when tail checking */ + if (flags & HEAP_TAIL_CHECKING_ENABLED) + { + for (size = 0; size < 64; size++) + { + p = HeapAlloc( GetProcessHeap(), 0, size ); + for (i = 0; i < 32; i++) if (p[size + i] != 0xab) break; + ok( i >= 8, "only %lu tail bytes for size %lu\n", i, size ); + HeapFree( GetProcessHeap(), 0, p ); + } + } } static void test_debug_heap( const char *argv0, DWORD flags ) diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 29e9559332e..c3fdf2c5d0b 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -106,6 +106,8 @@ C_ASSERT( sizeof(ARENA_LARGE) % LARGE_ALIGNMENT == 0 ); #define HEAP_MIN_SHRINK_SIZE (HEAP_MIN_DATA_SIZE+sizeof(ARENA_FREE)) /* minimum size to start allocating large blocks */ #define HEAP_MIN_LARGE_BLOCK_SIZE 0x7f000 +/* extra size to add at the end of block for tail checking */ +#define HEAP_TAIL_EXTRA_SIZE(flags) (flags & HEAP_TAIL_CHECKING_ENABLED ? 8 : 0) /* Max size of the blocks on the free lists */ static const SIZE_T HEAP_freeListSizes[] = @@ -677,7 +679,7 @@ static void HEAP_ShrinkBlock(SUBHEAP *subheap, ARENA_INUSE *pArena, SIZE_T size) static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size ) { ARENA_LARGE *arena; - SIZE_T block_size = sizeof(*arena) + ROUND_SIZE(size); + SIZE_T block_size = sizeof(*arena) + ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); LPVOID address = NULL; if (block_size < size) return NULL; /* overflow */ @@ -1581,7 +1583,7 @@ PVOID WINAPI RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size ) if (!heapPtr) return NULL; flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY; flags |= heapPtr->flags; - rounded_size = ROUND_SIZE(size); + rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE( flags ); if (rounded_size < size) /* overflow */ { if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY ); @@ -1735,7 +1737,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size flags |= heapPtr->flags; if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection ); - rounded_size = ROUND_SIZE(size); + rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); if (rounded_size < size) goto oom; /* overflow */ if (rounded_size < HEAP_MIN_DATA_SIZE) rounded_size = HEAP_MIN_DATA_SIZE;