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