diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 89566a1eb4f..5dc2d136bf4 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -218,6 +218,7 @@ MmDeleteVirtualMapping(struct _EPROCESS* Process, BOOL FreePage, BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalPage); +VOID MmUpdatePageDir(PULONG LocalPageDir); #define MM_PAGE_CLEAN (0) #define MM_PAGE_DIRTY (1) diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index 7a833026124..9e53b17dda2 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: process.c,v 1.11 2002/09/08 10:23:29 chorns Exp $ +/* $Id: process.c,v 1.12 2003/05/07 21:41:03 gvg Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/process.c @@ -44,6 +44,7 @@ KeAttachProcess (PEPROCESS Process) { KIRQL oldlvl; PETHREAD CurrentThread; + PULONG AttachedProcessPageDir; ULONG PageDir; DPRINT("KeAttachProcess(Process %x)\n",Process); @@ -57,10 +58,23 @@ KeAttachProcess (PEPROCESS Process) } KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); - + + /* The stack of the current process may be located in a page which is + not present in the page directory of the process we're attaching to. + That would lead to a page fault when this function returns. However, + since the processor can't call the page fault handler 'cause it can't + push EIP on the stack, this will show up as a stack fault which will + crash the entire system. + To prevent this, make sure the page directory of the process we're + attaching to is up-to-date. */ + + AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase); + MmUpdatePageDir(AttachedProcessPageDir); + ExUnmapPage(AttachedProcessPageDir); + CurrentThread->OldProcess = PsGetCurrentProcess(); CurrentThread->ThreadsProcess = Process; - PageDir = CurrentThread->ThreadsProcess->Pcb.DirectoryTableBase.u.LowPart; + PageDir = Process->Pcb.DirectoryTableBase.u.LowPart; DPRINT("Switching process context to %x\n",PageDir) __asm__("movl %0,%%cr3\n\t" : /* no inputs */ diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index 80de1851df4..6ccca8ba5bc 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: page.c,v 1.47 2002/11/05 21:13:15 dwelch Exp $ +/* $Id: page.c,v 1.48 2003/05/07 21:41:03 gvg Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/i386/page.c @@ -1213,4 +1213,23 @@ MmGetPhysicalAddress(PVOID vaddr) } +VOID +MmUpdatePageDir(PULONG LocalPageDir) +{ + unsigned Entry; + + for (Entry = ADDR_TO_PDE_OFFSET(KERNEL_BASE); + Entry < PAGE_SIZE / sizeof(LONG); + Entry++) + { + /* Skip the page directory */ + if (ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) != Entry && + 0 == LocalPageDir[Entry] && + 0 != MmGlobalKernelPageDirectory[Entry]) + { + LocalPageDir[Entry] = MmGlobalKernelPageDirectory[Entry]; + } + } +} + /* EOF */