https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7246909a80cdb8dc42098…
commit 7246909a80cdb8dc420981974c21bbbdbf0bd48b
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Sun Feb 3 13:57:21 2019 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Sun Feb 17 09:51:12 2019 +0100
[RTL] Protect pointer validity check in RtlFreeHeap with SEH.
Fixes crash in kernel32_winetest:heap.
---
sdk/lib/rtl/heap.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/sdk/lib/rtl/heap.c b/sdk/lib/rtl/heap.c
index 1c6df2996f..4d47ee2ec9 100644
--- a/sdk/lib/rtl/heap.c
+++ b/sdk/lib/rtl/heap.c
@@ -2180,28 +2180,36 @@ BOOLEAN NTAPI RtlFreeHeap(
if (RtlpHeapIsSpecial(Flags))
return RtlDebugFreeHeap(Heap, Flags, Ptr);
- /* Lock if necessary */
- if (!(Flags & HEAP_NO_SERIALIZE))
- {
- RtlEnterHeapLock(Heap->LockVariable, TRUE);
- 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))
+ /* 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)
{
- /* This is an invalid block */
+ /* The pointer was invalid */
DPRINT1("HEAP: Trying to free an invalid address %p!\n", Ptr);
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER);
+ _SEH2_YIELD(return FALSE);
+ }
- /* Release the heap lock */
- if (Locked) RtlLeaveHeapLock(Heap->LockVariable);
- return FALSE;
+ /* Lock if necessary */
+ if (!(Flags & HEAP_NO_SERIALIZE))
+ {
+ RtlEnterHeapLock(Heap->LockVariable, TRUE);
+ Locked = TRUE;
}
if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)