https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7246909a80cdb8dc420981...
commit 7246909a80cdb8dc420981974c21bbbdbf0bd48b Author: Thomas Faber thomas.faber@reactos.org AuthorDate: Sun Feb 3 13:57:21 2019 +0100 Commit: Thomas Faber thomas.faber@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)