mirror of
https://github.com/reactos/reactos.git
synced 2025-05-22 18:45:00 +00:00
[NTOS]: Implement MmDeleteTeb, VADs are now deleted/freed on thread exit as well (but the underlying page is still leaked). Should fix the advapi32 security crash.
[NTOS]: Sometimes it seems we hit some bad VADs due to bugs? in the AVL tree implementation. I'm going on vacation for a month and can't look at this, so I've hacked the code to ignore such VADs for now, in the interest of fixing the winetest regression. svn path=/trunk/; revision=48235
This commit is contained in:
parent
2384532846
commit
a28e798006
2 changed files with 63 additions and 2 deletions
|
@ -1121,4 +1121,16 @@ MiRemoveNode(
|
||||||
IN PMM_AVL_TABLE Table
|
IN PMM_AVL_TABLE Table
|
||||||
);
|
);
|
||||||
|
|
||||||
|
PMMADDRESS_NODE
|
||||||
|
NTAPI
|
||||||
|
MiGetPreviousNode(
|
||||||
|
IN PMMADDRESS_NODE Node
|
||||||
|
);
|
||||||
|
|
||||||
|
PMMADDRESS_NODE
|
||||||
|
NTAPI
|
||||||
|
MiGetNextNode(
|
||||||
|
IN PMMADDRESS_NODE Node
|
||||||
|
);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -149,8 +149,57 @@ NTAPI
|
||||||
MmDeleteTeb(IN PEPROCESS Process,
|
MmDeleteTeb(IN PEPROCESS Process,
|
||||||
IN PTEB Teb)
|
IN PTEB Teb)
|
||||||
{
|
{
|
||||||
/* Oops J */
|
ULONG_PTR TebEnd;
|
||||||
DPRINT("Leaking 4KB at thread exit, this will be fixed later\n");
|
PETHREAD Thread = PsGetCurrentThread();
|
||||||
|
PMMVAD Vad;
|
||||||
|
PMM_AVL_TABLE VadTree = &Process->VadRoot;
|
||||||
|
DPRINT("Deleting TEB: %p in %16s\n", Teb, Process->ImageFileName);
|
||||||
|
|
||||||
|
/* TEB is one page */
|
||||||
|
TebEnd = (ULONG_PTR)Teb + ROUND_TO_PAGES(sizeof(TEB)) - 1;
|
||||||
|
|
||||||
|
/* Attach to the process */
|
||||||
|
KeAttachProcess(&Process->Pcb);
|
||||||
|
|
||||||
|
/* Lock the process address space */
|
||||||
|
KeAcquireGuardedMutex(&Process->AddressCreationLock);
|
||||||
|
|
||||||
|
/* Find the VAD, make sure it's a TEB VAD */
|
||||||
|
Vad = MiLocateAddress(Teb);
|
||||||
|
DPRINT("Removing node for VAD: %lx %lx\n", Vad->StartingVpn, Vad->EndingVpn);
|
||||||
|
ASSERT(Vad != NULL);
|
||||||
|
if (Vad->StartingVpn != ((ULONG_PTR)Teb >> PAGE_SHIFT))
|
||||||
|
{
|
||||||
|
/* Bug in the AVL code? */
|
||||||
|
DPRINT1("Corrupted VAD!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Sanity checks for a valid TEB VAD */
|
||||||
|
ASSERT((Vad->StartingVpn == ((ULONG_PTR)Teb >> PAGE_SHIFT) &&
|
||||||
|
(Vad->EndingVpn == (TebEnd >> PAGE_SHIFT))));
|
||||||
|
ASSERT(Vad->u.VadFlags.NoChange == TRUE);
|
||||||
|
ASSERT(Vad->u2.VadFlags2.MultipleSecured == FALSE);
|
||||||
|
|
||||||
|
/* Lock the working set */
|
||||||
|
MiLockProcessWorkingSet(Process, Thread);
|
||||||
|
|
||||||
|
/* Remove this VAD from the tree */
|
||||||
|
ASSERT(VadTree->NumberGenericTableElements >= 1);
|
||||||
|
MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree);
|
||||||
|
|
||||||
|
/* Release the working set */
|
||||||
|
MiUnlockProcessWorkingSet(Process, Thread);
|
||||||
|
|
||||||
|
/* Remove the VAD */
|
||||||
|
ExFreePool(Vad);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the address space lock */
|
||||||
|
KeReleaseGuardedMutex(&Process->AddressCreationLock);
|
||||||
|
|
||||||
|
/* Detach */
|
||||||
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
Loading…
Reference in a new issue