[RTL] Protect pointer validity check in RtlFreeHeap with SEH.

Fixes crash in kernel32_winetest:heap.
This commit is contained in:
Thomas Faber 2019-02-03 13:57:21 +01:00
parent 3ddf59e1ed
commit 7246909a80
No known key found for this signature in database
GPG key ID: 076E7C3D44720826

View file

@ -2180,6 +2180,31 @@ BOOLEAN NTAPI RtlFreeHeap(
if (RtlpHeapIsSpecial(Flags))
return RtlDebugFreeHeap(Heap, Flags, Ptr);
/* Get pointer to the heap entry */
HeapEntry = (PHEAP_ENTRY)Ptr - 1;
/* Protect with SEH in case the pointer is not valid */
_SEH2_TRY
{
/* Check this entry, fail if it's invalid */
if (!(HeapEntry->Flags & HEAP_ENTRY_BUSY) ||
(((ULONG_PTR)Ptr & 0x7) != 0) ||
(HeapEntry->SegmentOffset >= HEAP_SEGMENTS))
{
/* This is an invalid block */
DPRINT1("HEAP: Trying to free an invalid address %p!\n", Ptr);
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER);
_SEH2_YIELD(return FALSE);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* The pointer was invalid */
DPRINT1("HEAP: Trying to free an invalid address %p!\n", Ptr);
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER);
_SEH2_YIELD(return FALSE);
}
/* Lock if necessary */
if (!(Flags & HEAP_NO_SERIALIZE))
{
@ -2187,23 +2212,6 @@ BOOLEAN NTAPI RtlFreeHeap(
Locked = TRUE;
}
/* Get pointer to the heap entry */
HeapEntry = (PHEAP_ENTRY)Ptr - 1;
/* Check this entry, fail if it's invalid */
if (!(HeapEntry->Flags & HEAP_ENTRY_BUSY) ||
(((ULONG_PTR)Ptr & 0x7) != 0) ||
(HeapEntry->SegmentOffset >= HEAP_SEGMENTS))
{
/* This is an invalid block */
DPRINT1("HEAP: Trying to free an invalid address %p!\n", Ptr);
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER);
/* Release the heap lock */
if (Locked) RtlLeaveHeapLock(Heap->LockVariable);
return FALSE;
}
if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
{
/* Big allocation */