Module Name:    src
Committed By:   martin
Date:           Sun Dec  8 14:31:58 UTC 2019

Modified Files:
        src/sys/arch/arm/arm32 [netbsd-9]: fault.c

Log Message:
Pull up following revision(s) (requested by ryo in ticket #510):

        sys/arch/arm/arm32/fault.c: revision 1.109

if Thumb-32 bit instruction located on a page boundariy, also need to consider 
the pc + 2 address.
Fix PR/54720. more detail and PoC are descrived in the PR.


To generate a diff of this commit:
cvs rdiff -u -r1.108 -r1.108.4.1 src/sys/arch/arm/arm32/fault.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/arm32/fault.c
diff -u src/sys/arch/arm/arm32/fault.c:1.108 src/sys/arch/arm/arm32/fault.c:1.108.4.1
--- src/sys/arch/arm/arm32/fault.c:1.108	Sat Apr  6 03:06:25 2019
+++ src/sys/arch/arm/arm32/fault.c	Sun Dec  8 14:31:57 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: fault.c,v 1.108 2019/04/06 03:06:25 thorpej Exp $	*/
+/*	$NetBSD: fault.c,v 1.108.4.1 2019/12/08 14:31:57 martin Exp $	*/
 
 /*
  * Copyright 2003 Wasabi Systems, Inc.
@@ -81,7 +81,7 @@
 #include "opt_kgdb.h"
 
 #include <sys/types.h>
-__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.108 2019/04/06 03:06:25 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.108.4.1 2019/12/08 14:31:57 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -838,6 +838,9 @@ prefetch_abort_handler(trapframe_t *tf)
 	UVMHIST_LOG(maphist, " (pc=0x%jx, l=0x%#jx, tf=0x%#jx)",
 	    fault_pc, (uintptr_t)l, (uintptr_t)tf, 0);
 
+#ifdef THUMB_CODE
+ recheck:
+#endif
 	/* Ok validate the address, can only execute in USER space */
 	if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS ||
 	    (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
@@ -897,6 +900,18 @@ do_trapsignal:
 	call_trapsignal(l, tf, &ksi);
 
 out:
+
+#ifdef THUMB_CODE
+#define THUMB_32BIT(hi) (((hi) & 0xe000) == 0xe000 && ((hi) & 0x1800))
+	/* thumb-32 instruction was located on page boundary? */
+	if ((tf->tf_spsr & PSR_T_bit) &&
+	    ((fault_pc & PAGE_MASK) == (PAGE_SIZE - THUMB_INSN_SIZE)) &&
+	    THUMB_32BIT(*(uint16_t *)tf->tf_pc)) {
+		fault_pc = tf->tf_pc + THUMB_INSN_SIZE;
+		goto recheck;
+	}
+#endif /* THUMB_CODE */
+
 	KASSERT(!TRAP_USERMODE(tf) || VALID_R15_PSR(tf->tf_pc, tf->tf_spsr));
 	userret(l);
 }

Reply via email to