Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/arm Check alignment of the fault PC before de-r...



details:   https://anonhg.NetBSD.org/src/rev/995616bda32a
branches:  trunk
changeset: 555334:995616bda32a
user:      scw <scw%NetBSD.org@localhost>
date:      Fri Nov 14 19:03:17 2003 +0000

description:
Check alignment of the fault PC before de-referencing it.
Give the process a Illegal Instruction fault if the PC is misaligned.

diffstat:

 sys/arch/arm/arm/syscall.c   |  27 +++++++++++++++++++++++++--
 sys/arch/arm/arm/undefined.c |  32 ++++++++++++++++++++++++--------
 2 files changed, 49 insertions(+), 10 deletions(-)

diffs (121 lines):

diff -r 2603d0b24196 -r 995616bda32a sys/arch/arm/arm/syscall.c
--- a/sys/arch/arm/arm/syscall.c        Fri Nov 14 19:00:03 2003 +0000
+++ b/sys/arch/arm/arm/syscall.c        Fri Nov 14 19:03:17 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: syscall.c,v 1.23 2003/10/31 03:28:12 simonb Exp $      */
+/*     $NetBSD: syscall.c,v 1.24 2003/11/14 19:03:17 scw Exp $ */
 
 /*-
  * Copyright (c) 2000, 2003 The NetBSD Foundation, Inc.
@@ -82,7 +82,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.23 2003/10/31 03:28:12 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.24 2003/11/14 19:03:17 scw Exp $");
 
 #include <sys/device.h>
 #include <sys/errno.h>
@@ -134,6 +134,29 @@
        frame->tf_pc += INSN_SIZE;
 #endif
 
+       /*
+        * Make sure the program counter is correctly aligned so we
+        * don't take an alignment fault trying to read the opcode.
+        */
+       if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
+               ksiginfo_t ksi;
+               /* Give the user an illegal instruction signal. */
+               KSI_INIT_TRAP(&ksi);
+               ksi.ksi_signo = SIGILL;
+               ksi.ksi_code = ILL_ILLOPC;
+               ksi.ksi_addr = (u_int32_t *)(intptr_t) (frame->tf_pc-INSN_SIZE);
+               KERNEL_PROC_LOCK(l->l_proc);
+#if 0
+               /* maybe one day we'll do emulations */
+               (*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
+#else
+               trapsignal(l, &ksi);
+#endif
+               KERNEL_PROC_UNLOCK(l->l_proc);
+               userret(l);
+               return;
+       }
+
        /* XXX fuword? */
 #ifdef __PROG32
        insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE);
diff -r 2603d0b24196 -r 995616bda32a sys/arch/arm/arm/undefined.c
--- a/sys/arch/arm/arm/undefined.c      Fri Nov 14 19:00:03 2003 +0000
+++ b/sys/arch/arm/arm/undefined.c      Fri Nov 14 19:03:17 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: undefined.c,v 1.20 2003/10/31 16:44:35 cl Exp $        */
+/*     $NetBSD: undefined.c,v 1.21 2003/11/14 19:03:17 scw Exp $       */
 
 /*
  * Copyright (c) 2001 Ben Harris.
@@ -54,7 +54,7 @@
 #include <sys/kgdb.h>
 #endif
 
-__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.20 2003/10/31 16:44:35 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: undefined.c,v 1.21 2003/11/14 19:03:17 scw Exp $");
 
 #include <sys/malloc.h>
 #include <sys/queue.h>
@@ -171,7 +171,6 @@
 void
 undefinedinstruction(trapframe_t *frame)
 {
-       struct proc *p;
        struct lwp *l;
        u_int fault_pc;
        int fault_instruction;
@@ -201,6 +200,27 @@
        fault_pc = frame->tf_pc;
 #endif
 
+       /* Get the current lwp/proc structure or lwp0/proc0 if there is none. */
+       l = curlwp == NULL ? &lwp0 : curlwp;
+
+       /*
+        * Make sure the program counter is correctly aligned so we
+        * don't take an alignment fault trying to read the opcode.
+        */
+       if (__predict_false((fault_pc & 3) != 0)) {
+               ksiginfo_t ksi;
+               /* Give the user an illegal instruction signal. */
+               KSI_INIT_TRAP(&ksi);
+               ksi.ksi_signo = SIGILL;
+               ksi.ksi_code = ILL_ILLOPC;
+               ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc;
+               KERNEL_PROC_LOCK(l);
+               trapsignal(l, &ksi);
+               KERNEL_PROC_UNLOCK(l);
+               userret(l);
+               return;
+       }
+
        /*
         * Should use fuword() here .. but in the interests of squeezing every
         * bit of speed we will just use ReadWord(). We know the instruction
@@ -228,10 +248,6 @@
        else
                coprocessor = 0;
 
-       /* Get the current lwp/proc structure or lwp0/proc0 if there is none. */
-       l = curlwp == NULL ? &lwp0 : curlwp;
-       p = l->l_proc;
-
 #ifdef __PROG26
        if ((frame->tf_r15 & R15_MODE) == R15_MODE_USR) {
 #else
@@ -321,6 +337,6 @@
        }
 
 #else
-       userret(p);
+       userret(l);
 #endif
 }



Home | Main Index | Thread Index | Old Index