From 9e6083e5c2c6aa8ce0529ab3097760c5595c132a Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 18 May 2014 14:59:31 +0000 Subject: [PATCH 1/1] [NTOSKRNL] - Do not ASSERT that a page fault im MmArmAccessFault happens on an invalid page. Instead handle write-on-readonly-PTE faults (Copy-on-write still unhandled). This ASSERT was not triggered so far, since ARM3 mapped all pages as read/write regardless of protection! So all (page file backed) sections mapped into user space were writable and could be happily modified from user mode! - Fix MI_MAKE_HARDWARE_PTE_USER, so that it respects the actual protection. svn path=/trunk/; revision=63354 --- reactos/ntoskrnl/mm/ARM3/miarm.h | 3 ++- reactos/ntoskrnl/mm/ARM3/pagfault.c | 32 +++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index 00566877b05..1a86f7e40fc 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -887,9 +887,10 @@ MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, ASSERT(MappingPte <= MiHighestUserPte); /* Start fresh */ - *NewPte = ValidKernelPte; + NewPte->u.Long = 0; /* Set the protection and page */ + NewPte->u.Hard.Valid = TRUE; NewPte->u.Hard.Owner = TRUE; NewPte->u.Hard.PageFrameNumber = PageFrameNumber; NewPte->u.Long |= MmProtectToPteMask[ProtectionMask]; diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index d8516bff64c..662d1ea9702 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -1835,9 +1835,37 @@ UserFault: ASSERT(MI_IS_PAGE_LARGE(PointerPde) == FALSE); } - /* Now capture the PTE. Ignore virtual faults for now */ + /* Now capture the PTE. */ TempPte = *PointerPte; - ASSERT(TempPte.u.Hard.Valid == 0); + + /* Check if the PTE is valid */ + if (TempPte.u.Hard.Valid) + { + /* Check if this is a write on a readonly PTE */ + if (StoreInstruction) + { + /* Is this a copy on write PTE? */ + if (TempPte.u.Hard.CopyOnWrite) + { + /* Not supported yet */ + ASSERT(FALSE); + } + + /* Is this a read-only PTE? */ + if (!TempPte.u.Hard.Write) + { + /* Return the status */ + MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread); + return STATUS_ACCESS_VIOLATION; + } + } + + /* FIXME: Execution is ignored for now, since we don't have no-execute pages yet */ + + /* The fault has already been resolved by a different thread */ + MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread); + return STATUS_SUCCESS; + } /* Quick check for demand-zero */ if (TempPte.u.Long == (MM_READWRITE << MM_PTE_SOFTWARE_PROTECTION_BITS)) -- 2.17.1