Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sh5/sh5 In sys___sigreturn14(), validate the saved ...



details:   https://anonhg.NetBSD.org/src/rev/e8dec7e373cc
branches:  trunk
changeset: 533949:e8dec7e373cc
user:      scw <scw%NetBSD.org@localhost>
date:      Thu Jul 11 14:15:32 2002 +0000

description:
In sys___sigreturn14(), validate the saved branch target registers and
program counter to avoid a possible kernel-mode IADDERR exception when
we try to restore the trapframe on return to user-mode.

diffstat:

 sys/arch/sh5/sh5/sig_machdep.c |  24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diffs (52 lines):

diff -r 3e2608287477 -r e8dec7e373cc sys/arch/sh5/sh5/sig_machdep.c
--- a/sys/arch/sh5/sh5/sig_machdep.c    Thu Jul 11 14:11:18 2002 +0000
+++ b/sys/arch/sh5/sh5/sig_machdep.c    Thu Jul 11 14:15:32 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sig_machdep.c,v 1.3 2002/07/10 15:55:02 scw Exp $      */
+/*     $NetBSD: sig_machdep.c,v 1.4 2002/07/11 14:15:32 scw Exp $      */
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -128,6 +128,7 @@
        tf->tf_state.sf_spc = (register_t)(uintptr_t)catcher;
        tf->tf_caller.r2 = sig;
        tf->tf_caller.r3 = code;
+       tf->tf_caller.r4 = (register_t)(uintptr_t)scp;
        tf->tf_caller.r15 = (register_t)(uintptr_t)scp;
 
        /* Remember that we're now on the signal stack. */
@@ -153,6 +154,8 @@
        } */ *uap = v;
        struct sigcontext *scp, ksc;
        struct trapframe *tf;
+       register_t effmask;
+       int i;
 
        tf = p->p_md.md_regs;
 
@@ -171,6 +174,25 @@
        if (ksc.sc_regs.r_intregs[24] != 0xACEBABE5ULL) /* magic number */
                return (EINVAL);
 
+       /*
+        * Validate the branch target registers. If don't, we risk
+        * a kernel-mode exception when trying to restore invalid
+        * values to them just before returning to user-mode.
+        */
+       effmask = ~((1ULL << SH5_NEFF_BITS) - 1);
+       for (i = 0; i < 8; i++) {
+               if ((llabs(ksc.sc_regs.r_tr[i]) & effmask) != 0 ||
+                   (ksc.sc_regs.r_tr[i] & 0x3) == 0x3)
+                       return (EINVAL);
+       }
+
+       /*
+        * Ditto for the PC
+        */
+       if ((llabs(ksc.sc_regs.r_pc) & effmask) != 0 ||
+           (ksc.sc_regs.r_pc & 0x3) == 0x3)
+               return (EINVAL);
+
        /* Restore register context. */
        process_write_regs(p, &ksc.sc_regs);
        if ((ksc.sc_fpstate & MDP_FPSAVED) != 0) {



Home | Main Index | Thread Index | Old Index