Author: tkreuzer Date: Sun May 18 14:59:31 2014 New Revision: 63354
URL: http://svn.reactos.org/svn/reactos?rev=63354&view=rev Log: [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.
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?re... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sun May 18 14:59:31 2014 @@ -887,9 +887,10 @@ 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];
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Sun May 18 14:59:31 2014 @@ -1835,9 +1835,37 @@ 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))