summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc/include/pcb.h9
-rw-r--r--sys/arch/sparc/include/ptrace.h3
-rw-r--r--sys/arch/sparc/sparc/genassym.cf3
-rw-r--r--sys/arch/sparc/sparc/locore.s122
-rw-r--r--sys/arch/sparc/sparc/machdep.c25
-rw-r--r--sys/arch/sparc/sparc/process_machdep.c11
-rw-r--r--sys/arch/sparc/sparc/vm_machdep.c3
7 files changed, 158 insertions, 18 deletions
diff --git a/sys/arch/sparc/include/pcb.h b/sys/arch/sparc/include/pcb.h
index 2c236368ab5..1383098c8d3 100644
--- a/sys/arch/sparc/include/pcb.h
+++ b/sys/arch/sparc/include/pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcb.h,v 1.3 1999/04/22 17:02:25 art Exp $ */
+/* $OpenBSD: pcb.h,v 1.4 2002/02/20 22:28:21 deraadt Exp $ */
/* $NetBSD: pcb.h,v 1.4 1995/03/28 18:19:56 jtc Exp $ */
/*
@@ -105,7 +105,7 @@ struct pcb {
int pcb_winof; /* number of window overflow traps */
int pcb_winuf; /* number of window underflow traps */
#endif
- int pcb_pad; /* pad to doubleword boundary */
+ u_int32_t pcb_wcookie; /* StackGhost cookie (must be unsigned) */
/* the following MUST be aligned on a doubleword boundary */
struct rwindow pcb_rw[PCB_MAXWIN]; /* saved windows */
@@ -118,8 +118,9 @@ struct pcb {
* stack itself need not be dumped).
*/
struct md_coredump {
- struct trapframe md_tf;
- struct fpstate md_fpstate;
+ struct trapframe md_tf;
+ struct fpstate md_fpstate;
+ u_int32_t md_wcookie;
};
#ifdef _KERNEL
diff --git a/sys/arch/sparc/include/ptrace.h b/sys/arch/sparc/include/ptrace.h
index 9253256060c..7cc86b633b4 100644
--- a/sys/arch/sparc/include/ptrace.h
+++ b/sys/arch/sparc/include/ptrace.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ptrace.h,v 1.2 1997/08/08 08:26:43 downsj Exp $ */
+/* $OpenBSD: ptrace.h,v 1.3 2002/02/20 22:28:21 deraadt Exp $ */
/* $NetBSD: ptrace.h,v 1.4 1994/11/20 20:53:27 deraadt Exp $ */
/*
@@ -52,3 +52,4 @@
#define PT_SETREGS (PT_FIRSTMACH + 1)
#define PT_GETFPREGS (PT_FIRSTMACH + 2)
#define PT_SETFPREGS (PT_FIRSTMACH + 3)
+#define PT_WCOOKIE (PT_FIRSTMACH + 4)
diff --git a/sys/arch/sparc/sparc/genassym.cf b/sys/arch/sparc/sparc/genassym.cf
index ed11982e239..721c9c926d5 100644
--- a/sys/arch/sparc/sparc/genassym.cf
+++ b/sys/arch/sparc/sparc/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.9 2002/01/16 20:50:17 miod Exp $
+# $OpenBSD: genassym.cf,v 1.10 2002/02/20 22:28:23 deraadt Exp $
# $NetBSD: genassym.cf,v 1.2 1997/06/28 19:59:04 pk Exp $
#
@@ -156,6 +156,7 @@ member pcb_sp
member pcb_pc
member pcb_uw
member pcb_wim
+member pcb_wcookie
# interrupt enable register PTE
define IE_REG_PTE_PG (PG_V | PG_W | PG_S | PG_NC | PG_OBIO)
diff --git a/sys/arch/sparc/sparc/locore.s b/sys/arch/sparc/sparc/locore.s
index a7f663c79af..439011af7f0 100644
--- a/sys/arch/sparc/sparc/locore.s
+++ b/sys/arch/sparc/sparc/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.44 2002/01/23 20:06:38 miod Exp $ */
+/* $OpenBSD: locore.s,v 1.45 2002/02/20 22:28:23 deraadt Exp $ */
/* $NetBSD: locore.s,v 1.73 1997/09/13 20:36:48 pk Exp $ */
/*
@@ -1559,15 +1559,18 @@ clean_trap_window:
save %g0, %g0, %g0 ! in any case, enter window to save
/* The window to be pushed is a kernel window. */
+ std %i6, [%sp + (7*8)]
std %l0, [%sp + (0*8)]
+
ctw_merge:
+ !! std %l0, [%sp + (0*8)] ! Done by delay slot or above
std %l2, [%sp + (1*8)]
std %l4, [%sp + (2*8)]
std %l6, [%sp + (3*8)]
std %i0, [%sp + (4*8)]
std %i2, [%sp + (5*8)]
std %i4, [%sp + (6*8)]
- std %i6, [%sp + (7*8)]
+ !! std %i6, [%sp + (7*8)] ! Done above or by StackGhost
/* Set up new window invalid mask, and update cpcb->pcb_wim. */
rd %psr, %g7 ! g7 = (junk << 5) + new_cwp
@@ -1587,6 +1590,16 @@ ctw_merge:
mov %l7, %g7 ! ... and g7
/* NOTREACHED */
+
+ctw_stackghost:
+ !! StackGhost Encrypt
+ sethi %hi(_cpcb), %g6 ! get current *pcb
+ ld [%g6 + %lo(_cpcb)], %g6 ! dereference *pcb
+ ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
+ xor %l0, %i7, %i7 ! mix in cookie
+ b ctw_merge
+ std %i6, [%sp + (7*8)]
+
ctw_user:
/*
* The window to be pushed is a user window.
@@ -1606,13 +1619,13 @@ ctw_user:
EMPTY
/* Note side-effect of SLT_IF_1PAGE_RW: decrements %g6 by 62 */
SLT_IF_1PAGE_RW(%sp, %g7, %g6)
- bl,a ctw_merge ! all ok if only 1
+ bl,a ctw_stackghost ! all ok if only 1
std %l0, [%sp]
add %sp, 7*8, %g5 ! check last addr too
add %g6, 62, %g6 ! restore %g6 to `pgofset'
PTE_OF_ADDR(%g5, %g7, ctw_invalid, %g6, NOP_ON_4M_3)
CMP_PTE_USER_WRITE(%g7, %g6, NOP_ON_4M_4)
- be,a ctw_merge ! all ok: store <l0,l1> and merge
+ be,a ctw_stackghost ! all ok: store <l0,l1> and merge
std %l0, [%sp]
/*
@@ -1643,7 +1656,13 @@ ctw_invalid:
std %i0, [%g5 + (4*8)]
std %i2, [%g5 + (5*8)]
std %i4, [%g5 + (6*8)]
+
+ !! StackGhost Encrypt (PCP)
+ ! pcb already dereferenced in %g6
+ ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
+ xor %l0, %i7, %i7 ! mix in cookie
std %i6, [%g5 + (7*8)]
+
deccc %g7 ! if (n > 0) save(), rw++;
bge,a 1b ! } while (--n >= 0);
save %g5, 64, %g5
@@ -2898,10 +2917,43 @@ winuf_invalid:
st %l0, [%g6 + PCB_WIM] ! cpcb->pcb_wim = cwp;
nop ! unnecessary? old wim was 0...
save %g0, %g0, %g0 ! back to I
- LOADWIN(%g6 + PCB_RW + 64) ! load from rw[1]
+
+ !!LOADWIN(%g6 + PCB_RW + 64) ! load from rw[1]
+
+ !! StackGhost Decrypt (PCP)
+ ! pcb already dereferenced in %g6
+ ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
+ ldd [%g6 + PCB_RW + 64 + 56], %i6
+ xor %l0, %i7, %i7 ! remove cookie
+
+ ldd [%g6 + PCB_RW + 64], %l0 ! load from rw[1]
+ ldd [%g6 + PCB_RW + 64 + 8], %l2
+ ldd [%g6 + PCB_RW + 64 + 16], %l4
+ ldd [%g6 + PCB_RW + 64 + 24], %l6
+ ldd [%g6 + PCB_RW + 64 + 32], %i0
+ ldd [%g6 + PCB_RW + 64 + 40], %i2
+ ldd [%g6 + PCB_RW + 64 + 48], %i4
+
save %g0, %g0, %g0 ! back to R
- LOADWIN(%g6 + PCB_RW) ! load from rw[0]
+
+ !! StackGhost Decrypt (PCP)
+ ! pcb already dereferenced in %g6
+ ! (If I was sober, I could potentially re-use the cookie from above)
+ ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
+ ldd [%g6 + PCB_RW + 56], %i6
+ xor %l0, %i7, %i7 ! remove cookie
+
+ !!LOADWIN(%g6 + PCB_RW) ! load from rw[0]
+ ldd [%g6 + PCB_RW], %l0 ! load from rw[0]
+ ldd [%g6 + PCB_RW + 8], %l2
+ ldd [%g6 + PCB_RW + 16], %l4
+ ldd [%g6 + PCB_RW + 24], %l6
+ ldd [%g6 + PCB_RW + 32], %i0
+ ldd [%g6 + PCB_RW + 40], %i2
+ ldd [%g6 + PCB_RW + 48], %i4
+
save %g0, %g0, %g0 ! back to T
+
wr %l0, 0, %psr ! restore condition codes
mov %l3, %g6 ! fix %g6
RETT
@@ -2920,7 +2972,24 @@ winuf_ok:
and %l0, 31, %l0
st %l0, [%l2 + PCB_WIM] ! cpcb->pcb_wim = cwp;
save %g0, %g0, %g0 ! back to I
- LOADWIN(%sp)
+
+ !! StackGhost Decrypt
+ sethi %hi(_cpcb), %l0 ! get current *pcb
+ ld [%l0 + %lo(_cpcb)], %l1 ! dereference *pcb
+ ld [%l1 + PCB_WCOOKIE], %l0 ! get window cookie
+ ldd [%sp + 56], %i6 ! get saved return pointer
+ xor %l0, %i7, %i7 ! remove cookie
+
+ !!LOADWIN(%sp)
+ ldd [%sp], %l0
+ ldd [%sp + 8], %l2
+ ldd [%sp + 16], %l4
+ ldd [%sp + 24], %l6
+ ldd [%sp + 32], %i0
+ ldd [%sp + 40], %i2
+ ldd [%sp + 48], %i4
+
+
save %g0, %g0, %g0 ! back to R
save %g0, %g0, %g0 ! back to T
wr %l0, 0, %psr ! restore condition codes
@@ -3061,7 +3130,23 @@ rft_user_ok:
and %l0, 31, %l0
st %l0, [%l1 + PCB_WIM] ! cpcb->pcb_wim = l0 & 31;
save %g0, %g0, %g0 ! back to window I
- LOADWIN(%sp) ! suck hard
+
+ !! StackGhost Decrypt
+ sethi %hi(_cpcb), %l0 ! get current *pcb
+ ld [%l0 + %lo(_cpcb)], %l1 ! dereference *pcb
+ ld [%l1 + PCB_WCOOKIE], %l0 ! get window cookie
+ ldd [%sp + 56], %i6 ! get saved return pointer
+ xor %l0, %i7, %i7 ! remove cookie
+
+ !!LOADWIN(%sp) ! suck hard
+ ldd [%sp], %l0
+ ldd [%sp + 8], %l2
+ ldd [%sp + 16], %l4
+ ldd [%sp + 24], %l6
+ ldd [%sp + 32], %i0
+ ldd [%sp + 40], %i2
+ ldd [%sp + 48], %i4
+
save %g0, %g0, %g0 ! back to window T
RETT
@@ -3139,7 +3224,22 @@ rft_user_or_recover_pcb_windows:
st %l0, [%g6 + PCB_WIM] ! cpcb->pcb_wim = CWP;
nop ! unnecessary? old wim was 0...
save %g0, %g0, %g0 ! back to window I
- LOADWIN(%g6 + PCB_RW)
+
+ !! StackGhost Decrypt (PCB)
+ ! pcb already deferenced in %g6
+ ld [%g6 + PCB_WCOOKIE], %l0 ! get window cookie
+ ldd [%g6 + PCB_RW + 56], %i6 ! get saved return pointer
+ xor %l0, %i7, %i7 ! remove cookie
+
+ !LOADWIN(%g6 + PCB_RW)
+ ldd [%g6 + PCB_RW], %l0
+ ldd [%g6 + PCB_RW + 8], %l2
+ ldd [%g6 + PCB_RW + 16], %l4
+ ldd [%g6 + PCB_RW + 24], %l6
+ ldd [%g6 + PCB_RW + 32], %i0
+ ldd [%g6 + PCB_RW + 40], %i2
+ ldd [%g6 + PCB_RW + 48], %i4
+
save %g0, %g0, %g0 ! back to window T (trap window)
wr %l0, 0, %psr ! cond codes, cond codes everywhere
mov %l3, %g6 ! restore g6
@@ -6453,6 +6553,10 @@ _cold:
_proc0paddr:
.word _u0 ! KVA of proc0 uarea
+! StackGhost: added 2 symbols to ease debugging
+ .globl slowtrap
+ .globl winuf_invalid
+
/* interrupt counters XXX THESE BELONG ELSEWHERE (if anywhere) */
.globl _intrcnt, _eintrcnt, _intrnames, _eintrnames
_intrnames:
diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c
index bd33985c129..7026027154e 100644
--- a/sys/arch/sparc/sparc/machdep.c
+++ b/sys/arch/sparc/sparc/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.79 2002/02/17 22:59:53 maja Exp $ */
+/* $OpenBSD: machdep.c,v 1.80 2002/02/20 22:28:23 deraadt Exp $ */
/* $NetBSD: machdep.c,v 1.85 1997/09/12 08:55:02 pk Exp $ */
/*
@@ -78,6 +78,8 @@
#include <uvm/uvm_extern.h>
+#include <dev/rndvar.h>
+
#include <machine/autoconf.h>
#include <machine/frame.h>
#include <machine/cpu.h>
@@ -368,6 +370,27 @@ setregs(p, pack, stack, retval)
struct fpstate *fs;
int psr;
+ /* Setup the process StackGhost cookie which will be XORed into
+ * the return pointer as register windows are over/underflowed
+ */
+ p->p_addr->u_pcb.pcb_wcookie = 0; /* XXX later arc4random(); */
+
+ /* The cookie needs to guarantee invalid alignment after the XOR */
+ switch (p->p_addr->u_pcb.pcb_wcookie % 3) {
+ case 0: /* Two lsb's already both set except if the cookie is 0 */
+ p->p_addr->u_pcb.pcb_wcookie |= 0x3;
+ break;
+ case 1: /* Set the lsb */
+ p->p_addr->u_pcb.pcb_wcookie = 1 |
+ (p->p_addr->u_pcb.pcb_wcookie & ~0x3);
+ break;
+ case 2: /* Set the second most lsb */
+ p->p_addr->u_pcb.pcb_wcookie = 2 |
+ (p->p_addr->u_pcb.pcb_wcookie & ~0x3);
+ break;
+ }
+
+
/* Don't allow misaligned code by default */
p->p_md.md_flags &= ~MDP_FIXALIGN;
diff --git a/sys/arch/sparc/sparc/process_machdep.c b/sys/arch/sparc/sparc/process_machdep.c
index afaa37a2342..f5354856add 100644
--- a/sys/arch/sparc/sparc/process_machdep.c
+++ b/sys/arch/sparc/sparc/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.3 1997/08/08 08:27:39 downsj Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.4 2002/02/20 22:28:23 deraadt Exp $ */
/* $NetBSD: process_machdep.c,v 1.6 1996/03/14 21:09:26 christos Exp $ */
/*
@@ -74,6 +74,8 @@
#include <machine/frame.h>
#include <sys/ptrace.h>
+u_int32_t process_get_wcookie(struct proc *p);
+
int
process_read_regs(p, regs)
struct proc *p;
@@ -141,3 +143,10 @@ struct fpreg *regs;
bcopy(regs, p->p_md.md_fpstate, sizeof(struct fpreg));
return 0;
}
+
+u_int32_t
+process_get_wcookie(p)
+ struct proc *p;
+{
+ return p->p_addr->u_pcb.pcb_wcookie;
+}
diff --git a/sys/arch/sparc/sparc/vm_machdep.c b/sys/arch/sparc/sparc/vm_machdep.c
index e7f51936934..1e3d4a756f1 100644
--- a/sys/arch/sparc/sparc/vm_machdep.c
+++ b/sys/arch/sparc/sparc/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.42 2002/01/16 20:50:17 miod Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.43 2002/02/20 22:28:23 deraadt Exp $ */
/* $NetBSD: vm_machdep.c,v 1.30 1997/03/10 23:55:40 pk Exp $ */
/*
@@ -524,6 +524,7 @@ cpu_coredump(p, vp, cred, chdr)
chdr->c_cpusize = sizeof(md_core);
md_core.md_tf = *p->p_md.md_tf;
+ md_core.md_wcookie = p->p_addr->u_pcb.pcb_wcookie;
if (p->p_md.md_fpstate) {
if (p == cpuinfo.fpproc)
savefpstate(p->p_md.md_fpstate);