[RTL/DPH]

- Do not merge memory blocks if they don't belong to the same VM "region" (ie not allocated from the same NtAllocateVirtualMemory call)
Fixes failures of ZwProtectVirtualMemory calls.
Bugs see DPH rollin', they hatin'

svn path=/trunk/; revision=66336
This commit is contained in:
Jérôme Gardou 2015-02-17 15:08:47 +00:00
parent ddaa717558
commit 52a5043b98

View file

@ -691,12 +691,35 @@ RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot,
/* Check the previous node and merge if possible */
if (PrevNode->pVirtualBlock + PrevNode->nVirtualBlockSize == Node->pVirtualBlock)
{
/* They are adjacent - merge! */
PrevNode->nVirtualBlockSize += Node->nVirtualBlockSize;
RtlpDphReturnNodeToUnusedList(DphRoot, Node);
DphRoot->nAvailableAllocations--;
/* Check they actually belong to the same virtual memory block */
NTSTATUS Status;
MEMORY_BASIC_INFORMATION MemoryBasicInfo;
Node = PrevNode;
Status = ZwQueryVirtualMemory(
ZwCurrentProcess(),
Node->pVirtualBlock,
MemoryBasicInformation,
&MemoryBasicInfo,
sizeof(MemoryBasicInfo),
NULL);
/* There is no way this can fail, we committed this memory! */
ASSERT(NT_SUCCESS(Status));
if ((PUCHAR)MemoryBasicInfo.AllocationBase <= PrevNode->pVirtualBlock)
{
/* They are adjacent, and from the same VM region. - merge! */
PrevNode->nVirtualBlockSize += Node->nVirtualBlockSize;
RtlpDphReturnNodeToUnusedList(DphRoot, Node);
DphRoot->nAvailableAllocations--;
Node = PrevNode;
}
else
{
/* Insert after PrevNode */
InsertTailList(&PrevNode->AvailableEntry, &Node->AvailableEntry);
}
}
else
{
@ -711,13 +734,31 @@ RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot,
/* Node is not at the tail of the list, check if it's adjacent */
if (Node->pVirtualBlock + Node->nVirtualBlockSize == NextNode->pVirtualBlock)
{
/* They are adjacent - merge! */
Node->nVirtualBlockSize += NextNode->nVirtualBlockSize;
/* Check they actually belong to the same virtual memory block */
NTSTATUS Status;
MEMORY_BASIC_INFORMATION MemoryBasicInfo;
/* Remove next entry from the list and put it into unused entries list */
RemoveEntryList(&NextNode->AvailableEntry);
RtlpDphReturnNodeToUnusedList(DphRoot, NextNode);
DphRoot->nAvailableAllocations--;
Status = ZwQueryVirtualMemory(
ZwCurrentProcess(),
NextNode->pVirtualBlock,
MemoryBasicInformation,
&MemoryBasicInfo,
sizeof(MemoryBasicInfo),
NULL);
/* There is no way this can fail, we committed this memory! */
ASSERT(NT_SUCCESS(Status));
if ((PUCHAR)MemoryBasicInfo.AllocationBase <= Node->pVirtualBlock)
{
/* They are adjacent - merge! */
Node->nVirtualBlockSize += NextNode->nVirtualBlockSize;
/* Remove next entry from the list and put it into unused entries list */
RemoveEntryList(&NextNode->AvailableEntry);
RtlpDphReturnNodeToUnusedList(DphRoot, NextNode);
DphRoot->nAvailableAllocations--;
}
}
}
}