diff options
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/sparc/include/pcb.h | 9 | ||||
-rw-r--r-- | sys/arch/sparc/include/ptrace.h | 3 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/genassym.cf | 3 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/locore.s | 122 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/machdep.c | 25 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/process_machdep.c | 11 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/vm_machdep.c | 3 |
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); |