[NTOS:MM] Add support for NX page-faults

This commit is contained in:
Timo Kreuzer 2018-01-02 11:22:22 +01:00
parent 4d043aa05e
commit a00378a1a1
4 changed files with 40 additions and 1 deletions

View file

@ -98,6 +98,7 @@
#define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Writable == 1)
#endif
#define MI_IS_PAGE_COPY_ON_WRITE(x)((x)->u.Hard.CopyOnWrite == 1)
#define MI_IS_PAGE_EXECUTABLE(x) ((x)->u.Hard.NoExecute == 0)
#define MI_IS_PAGE_DIRTY(x) ((x)->u.Hard.Dirty == 1)
#define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
#if !defined(CONFIG_SMP)
@ -109,6 +110,7 @@
/* Macros to identify the page fault reason from the error code */
#define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x1)
#define MI_IS_WRITE_ACCESS(FaultCode) BooleanFlagOn(FaultCode, 0x2)
#define MI_IS_INSTRUCTION_FETCH(FaultCode) BooleanFlagOn(FaultCode, 0x10)
/* On x64, these are the same */
#define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE

View file

@ -84,6 +84,7 @@
#define MI_IS_PAGE_LARGE(x) FALSE
#define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.ReadOnly == 0)
#define MI_IS_PAGE_COPY_ON_WRITE(x)FALSE
#define MI_IS_PAGE_EXECUTABLE(x) TRUE
#define MI_IS_PAGE_DIRTY(x) TRUE
#define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.ReadOnly = 0)
@ -91,6 +92,7 @@
/* Macros to identify the page fault reason from the error code */
#define MI_IS_NOT_PRESENT_FAULT(FaultCode) TRUE
#define MI_IS_WRITE_ACCESS(FaultCode) TRUE
#define MI_IS_INSTRUCTION_FETCH(FaultCode) FALSE
/* Convert an address to a corresponding PTE */
#define MiAddressToPte(x) \

View file

@ -103,6 +103,11 @@
#define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Writable == 1)
#endif
#define MI_IS_PAGE_COPY_ON_WRITE(x)((x)->u.Hard.CopyOnWrite == 1)
#ifdef _PAE_
#define MI_IS_PAGE_EXECUTABLE(x) ((x)->u.Hard.NoExecute == 0)
#else
#define MI_IS_PAGE_EXECUTABLE(x) TRUE
#endif
#define MI_IS_PAGE_DIRTY(x) ((x)->u.Hard.Dirty == 1)
#define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
#if !defined(CONFIG_SMP)
@ -115,6 +120,7 @@
/* Macros to identify the page fault reason from the error code */
#define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x1)
#define MI_IS_WRITE_ACCESS(FaultCode) BooleanFlagOn(FaultCode, 0x2)
#define MI_IS_INSTRUCTION_FETCH(FaultCode) BooleanFlagOn(FaultCode, 0x10)
/* On x86, these two are the same */
#define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE

View file

@ -1780,6 +1780,17 @@ MmArmAccessFault(IN ULONG FaultCode,
11);
}
}
/* Check for execution of non-executable memory */
if (MI_IS_INSTRUCTION_FETCH(FaultCode) &&
!MI_IS_PAGE_EXECUTABLE(&TempPte))
{
KeBugCheckEx(ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY,
(ULONG_PTR)Address,
(ULONG_PTR)TempPte.u.Long,
(ULONG_PTR)TrapInformation,
1);
}
}
/* Release PFN lock and return all good */
@ -1886,6 +1897,17 @@ _WARN("Session space stuff is not implemented yet!")
}
}
/* Check for execution of non-executable memory */
if (MI_IS_INSTRUCTION_FETCH(FaultCode) &&
!MI_IS_PAGE_EXECUTABLE(&TempPte))
{
KeBugCheckEx(ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY,
(ULONG_PTR)Address,
(ULONG_PTR)TempPte.u.Long,
(ULONG_PTR)TrapInformation,
2);
}
/* Check for read-only write in session space */
if ((IsSessionAddress) &&
MI_IS_WRITE_ACCESS(FaultCode) &&
@ -2196,7 +2218,14 @@ UserFault:
}
}
/* FIXME: Execution is ignored for now, since we don't have no-execute pages yet */
/* Check for execution of non-executable memory */
if (MI_IS_INSTRUCTION_FETCH(FaultCode) &&
!MI_IS_PAGE_EXECUTABLE(&TempPte))
{
/* Return the status */
MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
return STATUS_ACCESS_VIOLATION;
}
/* The fault has already been resolved by a different thread */
MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);