From 3bfbf2fb53dedfcc31990d32af82f43a35f0d5f3 Mon Sep 17 00:00:00 2001
From: David Karoly <karolyd577@gmail.com>
Date: Mon, 5 Sep 2022 13:44:07 +0200
Subject: [PATCH] kernel/arm: check for PXN and alignment fault in page fault
 handler

Change-Id: I2a863b57b1252343c9c029d1bb5af8d328558576
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5620
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
---
 headers/private/system/arch/arm/arch_cpu_defs.h | 5 +++++
 src/system/kernel/arch/arm/arch_int.cpp         | 6 ++++++
 2 files changed, 11 insertions(+)

diff --git a/headers/private/system/arch/arm/arch_cpu_defs.h b/headers/private/system/arch/arm/arch_cpu_defs.h
index 631373bc4a..2ca5a8bc70 100644
--- a/headers/private/system/arch/arm/arch_cpu_defs.h
+++ b/headers/private/system/arch/arm/arch_cpu_defs.h
@@ -25,5 +25,10 @@
 #define CPSR_I				0x80
 
 #define FSR_WNR				0x800
+#define FSR_LPAE			0x200
+
+#define FSR_FS_ALIGNMENT_FAULT		0x01
+#define FSR_FS_PERMISSION_FAULT_L1	0x0d
+#define FSR_FS_PERMISSION_FAULT_L2	0x0f
 
 #endif	/* _SYSTEM_ARCH_ARM_DEFS_H */
diff --git a/src/system/kernel/arch/arm/arch_int.cpp b/src/system/kernel/arch/arm/arch_int.cpp
index e59a1b758d..19a6c6198c 100644
--- a/src/system/kernel/arch/arm/arch_int.cpp
+++ b/src/system/kernel/arch/arm/arch_int.cpp
@@ -328,6 +328,12 @@ arch_arm_page_fault(struct iframe *frame, addr_t far, uint32 fsr, bool isWrite,
 		panic("page fault in debugger without fault handler! Touching "
 			"address %p from pc %p\n", (void *)far, (void *)frame->pc);
 		return;
+	} else if (isExec && !isUser && (far < KERNEL_BASE) &&
+		(((fsr & 0x060f) == FSR_FS_PERMISSION_FAULT_L1) || ((fsr & 0x060f) == FSR_FS_PERMISSION_FAULT_L2))) {
+		panic("PXN violation trying to execute user-mapped address 0x%08" B_PRIxADDR " from kernel mode\n",
+			far);
+	} else if (!isExec && ((fsr & 0x060f) == FSR_FS_ALIGNMENT_FAULT)) {
+		panic("unhandled alignment exception\n");
 	} else if ((frame->spsr & CPSR_I) != 0) {
 		// interrupts disabled