summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r--sys/arch/sparc64/include/pcb.h5
-rw-r--r--sys/arch/sparc64/include/ptrace.h7
-rw-r--r--sys/arch/sparc64/sparc64/genassym.cf3
-rw-r--r--sys/arch/sparc64/sparc64/locore.s69
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c25
-rw-r--r--sys/arch/sparc64/sparc64/process_machdep.c8
-rw-r--r--sys/arch/sparc64/sparc64/trap.c9
-rw-r--r--sys/arch/sparc64/sparc64/vm_machdep.c3
8 files changed, 109 insertions, 20 deletions
diff --git a/sys/arch/sparc64/include/pcb.h b/sys/arch/sparc64/include/pcb.h
index a0f4e42f856..43d19b7bd64 100644
--- a/sys/arch/sparc64/include/pcb.h
+++ b/sys/arch/sparc64/include/pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcb.h,v 1.4 2003/06/02 23:27:56 millert Exp $ */
+/* $OpenBSD: pcb.h,v 1.5 2005/03/29 19:34:07 kettenis Exp $ */
/* $NetBSD: pcb.h,v 1.7 2000/12/29 17:12:05 eeh Exp $ */
/*
@@ -136,6 +136,8 @@ struct pcb {
char pcb_pil; /* %pil when switch() was called -- prolly not needed */
const char *lastcall; /* DEBUG -- name of last system call */
+ u_int64_t pcb_wcookie;
+
/* the following MUST be aligned on a 64-bit boundary */
struct rwindow64 pcb_rw[PCB_MAXWIN]; /* saved windows */
};
@@ -149,6 +151,7 @@ struct pcb {
struct md_coredump {
struct trapframe64 md_tf;
struct fpstate64 md_fpstate;
+ u_int64_t md_wcookie;
};
#ifdef _KERNEL
diff --git a/sys/arch/sparc64/include/ptrace.h b/sys/arch/sparc64/include/ptrace.h
index 194d9521ecb..36de9393fc2 100644
--- a/sys/arch/sparc64/include/ptrace.h
+++ b/sys/arch/sparc64/include/ptrace.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ptrace.h,v 1.2 2003/06/02 23:27:56 millert Exp $ */
+/* $OpenBSD: ptrace.h,v 1.3 2005/03/29 19:34:07 kettenis Exp $ */
/* $NetBSD: ptrace.h,v 1.1.1.1 1998/06/20 04:58:52 eeh Exp $ */
/*
@@ -48,3 +48,8 @@
#define PT_SETREGS (PT_FIRSTMACH + 1)
#define PT_GETFPREGS (PT_FIRSTMACH + 2)
#define PT_SETFPREGS (PT_FIRSTMACH + 3)
+#define PT_WCOOKIE (PT_FIRSTMACH + 4)
+
+#ifdef _KERNEL
+register_t process_get_wcookie(struct proc *p);
+#endif
diff --git a/sys/arch/sparc64/sparc64/genassym.cf b/sys/arch/sparc64/sparc64/genassym.cf
index f19519b2620..170bb345012 100644
--- a/sys/arch/sparc64/sparc64/genassym.cf
+++ b/sys/arch/sparc64/sparc64/genassym.cf
@@ -1,4 +1,4 @@
-# $OpenBSD: genassym.cf,v 1.13 2004/12/01 14:31:25 miod Exp $
+# $OpenBSD: genassym.cf,v 1.14 2005/03/29 19:34:07 kettenis Exp $
# $NetBSD: genassym.cf,v 1.23 2001/08/08 00:09:30 eeh Exp $
#
@@ -189,6 +189,7 @@ member pcb_cwp
member pcb_pil
member pcb_rw
member pcb_sp
+member pcb_wcookie
member pcb_pc
member PCB_LASTCALL lastcall
define PCB_SIZE sizeof(struct pcb)
diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s
index d20edf6bca9..4be5bdc286b 100644
--- a/sys/arch/sparc64/sparc64/locore.s
+++ b/sys/arch/sparc64/sparc64/locore.s
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.48 2004/12/24 22:50:31 miod Exp $ */
+/* $OpenBSD: locore.s,v 1.49 2005/03/29 19:34:07 kettenis Exp $ */
/* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */
/*
@@ -598,7 +598,38 @@ _C_LABEL(cold):
* Here are some often repeated traps as macros.
*/
- ! spill a 64-bit register window
+ ! spill a 64-bit user register window
+ .macro USPILL64 label, as
+\label:
+ wr %g0, \as, %asi
+ stxa %l0, [%sp + BIAS + ( 0*8)] %asi
+ stxa %l1, [%sp + BIAS + ( 1*8)] %asi
+ stxa %l2, [%sp + BIAS + ( 2*8)] %asi
+ stxa %l3, [%sp + BIAS + ( 3*8)] %asi
+ stxa %l4, [%sp + BIAS + ( 4*8)] %asi
+ stxa %l5, [%sp + BIAS + ( 5*8)] %asi
+ stxa %l6, [%sp + BIAS + ( 6*8)] %asi
+ stxa %l7, [%sp + BIAS + ( 7*8)] %asi
+ stxa %i0, [%sp + BIAS + ( 8*8)] %asi
+ stxa %i1, [%sp + BIAS + ( 9*8)] %asi
+ stxa %i2, [%sp + BIAS + (10*8)] %asi
+ stxa %i3, [%sp + BIAS + (11*8)] %asi
+ stxa %i4, [%sp + BIAS + (12*8)] %asi
+ stxa %i5, [%sp + BIAS + (13*8)] %asi
+ stxa %i6, [%sp + BIAS + (14*8)] %asi
+ sethi %hi(CPCB), %g5
+ ldx [%g5 + %lo(CPCB)], %g5
+ ldx [%g5 + PCB_WCOOKIE], %g5
+ xor %g5, %i7, %g5 ! stackghost
+ stxa %g5, [%sp + BIAS + (15*8)] %asi
+ saved
+ CLRTT 1
+ retry
+ NOTREACHED
+ TA32
+ .endm
+
+ ! spill a 64-bit kernel register window
.macro SPILL64 label, as
\label:
wr %g0, \as, %asi
@@ -634,7 +665,23 @@ _C_LABEL(cold):
TA32
.endm
- ! fill a 64-bit register window
+ ! fill a 64-bit user register window
+ .macro UFILL64 label, as
+\label:
+ wr %g0, \as, %asi
+ FILL ldxa, %sp+BIAS, 8, %asi
+ sethi %hi(CPCB), %g5
+ ldx [%g5 + %lo(CPCB)], %g5
+ ldx [%g5 + PCB_WCOOKIE], %g5
+ xor %g5, %i7, %i7 ! stackghost
+ restored
+ CLRTT 3
+ retry
+ NOTREACHED
+ TA32
+ .endm
+
+ ! fill a 64-bit kernel register window
.macro FILL64 label, as
\label:
wr %g0, \as, %asi
@@ -750,7 +797,7 @@ ufast_DMMU_protection: ! 06c = fast data access MMU protection
UTRAP 0x077; UTRAP 0x078; UTRAP 0x079; UTRAP 0x07a; UTRAP 0x07b; UTRAP 0x07c
UTRAP 0x07d; UTRAP 0x07e; UTRAP 0x07f
TABLE/**/uspill:
- SPILL64 uspill8,ASI_AIUS ! 0x080 spill_0_normal -- used to save user windows in user mode
+ USPILL64 uspill8,ASI_AIUS ! 0x080 spill_0_normal -- used to save user windows in user mode
SPILL32 uspill4,ASI_AIUS ! 0x084 spill_1_normal
SPILLBOTH uspill8,uspill4,ASI_AIUS ! 0x088 spill_2_normal
#ifdef DEBUG
@@ -763,7 +810,7 @@ TABLE/**/kspill:
SPILLBOTH kspill8,kspill4,ASI_N ! 0x098 spill_6_normal
UTRAP 0x09c; TA32 ! 0x09c spill_7_normal
TABLE/**/uspillk:
- SPILL64 uspillk8,ASI_AIUS ! 0x0a0 spill_0_other -- used to save user windows in supervisor mode
+ USPILL64 uspillk8,ASI_AIUS ! 0x0a0 spill_0_other -- used to save user windows in supervisor mode
SPILL32 uspillk4,ASI_AIUS ! 0x0a4 spill_1_other
SPILLBOTH uspillk8,uspillk4,ASI_AIUS ! 0x0a8 spill_2_other
UTRAP 0x0ac; TA32 ! 0x0ac spill_3_other
@@ -772,7 +819,7 @@ TABLE/**/uspillk:
UTRAP 0x0b8; TA32 ! 0x0b8 spill_6_other
UTRAP 0x0bc; TA32 ! 0x0bc spill_7_other
TABLE/**/ufill:
- FILL64 ufill8,ASI_AIUS ! 0x0c0 fill_0_normal -- used to fill windows when running user mode
+ UFILL64 ufill8,ASI_AIUS ! 0x0c0 fill_0_normal -- used to fill windows when running user mode
FILL32 ufill4,ASI_AIUS ! 0x0c4 fill_1_normal
FILLBOTH ufill8,ufill4,ASI_AIUS ! 0x0c8 fill_2_normal
UTRAP 0x0cc; TA32 ! 0x0cc fill_3_normal
@@ -782,7 +829,7 @@ TABLE/**/kfill:
FILLBOTH kfill8,kfill4,ASI_N ! 0x0d8 fill_6_normal
UTRAP 0x0dc; TA32 ! 0x0dc fill_7_normal
TABLE/**/ufillk:
- FILL64 ufillk8,ASI_AIUS ! 0x0e0 fill_0_other
+ UFILL64 ufillk8,ASI_AIUS ! 0x0e0 fill_0_other
FILL32 ufillk4,ASI_AIUS ! 0x0e4 fill_1_other
FILLBOTH ufillk8,ufillk4,ASI_AIUS ! 0x0e8 fill_2_other
UTRAP 0x0ec; TA32 ! 0x0ec fill_3_other
@@ -912,7 +959,7 @@ kfast_DMMU_protection: ! 06c = fast data access MMU protection
UTRAP 0x077; UTRAP 0x078; UTRAP 0x079; UTRAP 0x07a; UTRAP 0x07b; UTRAP 0x07c
UTRAP 0x07d; UTRAP 0x07e; UTRAP 0x07f
TABLE/**/uspill:
- SPILL64 1,ASI_AIUS ! 0x080 spill_0_normal -- used to save user windows
+ USPILL64 1,ASI_AIUS ! 0x080 spill_0_normal -- used to save user windows
SPILL32 2,ASI_AIUS ! 0x084 spill_1_normal
SPILLBOTH 1b,2b,ASI_AIUS ! 0x088 spill_2_normal
UTRAP 0x08c; TA32 ! 0x08c spill_3_normal
@@ -922,7 +969,7 @@ TABLE/**/kspill:
SPILLBOTH 1b,2b,ASI_N ! 0x098 spill_6_normal
UTRAP 0x09c; TA32 ! 0x09c spill_7_normal
TABLE/**/uspillk:
- SPILL64 1,ASI_AIUS ! 0x0a0 spill_0_other -- used to save user windows in nucleus mode
+ USPILL64 1,ASI_AIUS ! 0x0a0 spill_0_other -- used to save user windows in nucleus mode
SPILL32 2,ASI_AIUS ! 0x0a4 spill_1_other
SPILLBOTH 1b,2b,ASI_AIUS ! 0x0a8 spill_2_other
UTRAP 0x0ac; TA32 ! 0x0ac spill_3_other
@@ -931,7 +978,7 @@ TABLE/**/uspillk:
UTRAP 0x0b8; TA32 ! 0x0b8 spill_6_other
UTRAP 0x0bc; TA32 ! 0x0bc spill_7_other
TABLE/**/ufill:
- FILL64 1,ASI_AIUS ! 0x0c0 fill_0_normal -- used to fill windows when running nucleus mode from user
+ UFILL64 1,ASI_AIUS ! 0x0c0 fill_0_normal -- used to fill windows when running nucleus mode from user
FILL32 2,ASI_AIUS ! 0x0c4 fill_1_normal
FILLBOTH 1b,2b,ASI_AIUS ! 0x0c8 fill_2_normal
UTRAP 0x0cc; TA32 ! 0x0cc fill_3_normal
@@ -941,7 +988,7 @@ TABLE/**/sfill:
FILLBOTH 1b,2b,ASI_N ! 0x0d8 fill_6_normal
UTRAP 0x0dc; TA32 ! 0x0dc fill_7_normal
TABLE/**/kfill:
- FILL64 1,ASI_AIUS ! 0x0e0 fill_0_other -- used to fill user windows when running nucleus mode -- will we ever use this?
+ UFILL64 1,ASI_AIUS ! 0x0e0 fill_0_other -- used to fill user windows when running nucleus mode -- will we ever use this?
FILL32 2,ASI_AIUS ! 0x0e4 fill_1_other
FILLBOTH 1b,2b,ASI_AIUS ! 0x0e8 fill_2_other
UTRAP 0x0ec; TA32 ! 0x0ec fill_3_other
diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c
index 5e1a341b10c..b4b34288760 100644
--- a/sys/arch/sparc64/sparc64/machdep.c
+++ b/sys/arch/sparc64/sparc64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.74 2004/11/02 21:20:59 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.75 2005/03/29 19:34:07 kettenis Exp $ */
/* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */
/*-
@@ -102,6 +102,7 @@
#include <sys/sysctl.h>
#include <sys/exec_elf.h>
+#include <dev/rndvar.h>
#ifdef SYSVMSG
#include <sys/msg.h>
@@ -398,6 +399,28 @@ setregs(p, pack, stack, retval)
int pstate = PSTATE_USER;
Elf_Ehdr *eh = pack->ep_hdr;
+ /*
+ * 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 = ((u_int64_t)arc4random() << 32) |
+ 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/sparc64/sparc64/process_machdep.c b/sys/arch/sparc64/sparc64/process_machdep.c
index 77cf99b470c..381f7a5f254 100644
--- a/sys/arch/sparc64/sparc64/process_machdep.c
+++ b/sys/arch/sparc64/sparc64/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.6 2003/06/02 23:27:56 millert Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.7 2005/03/29 19:34:07 kettenis Exp $ */
/* $NetBSD: process_machdep.c,v 1.10 2000/09/26 22:05:50 eeh Exp $ */
/*
@@ -231,4 +231,10 @@ process_write_fpregs(p, regs)
return 0;
}
+register_t
+process_get_wcookie(struct proc *p)
+{
+ return p->p_addr->u_pcb.pcb_wcookie;
+}
+
#endif /* PTRACE */
diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c
index b7c73f51d41..47795b3b5ca 100644
--- a/sys/arch/sparc64/sparc64/trap.c
+++ b/sys/arch/sparc64/sparc64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.33 2004/12/06 20:12:25 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.34 2005/03/29 19:34:07 kettenis Exp $ */
/* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */
/*
@@ -758,9 +758,12 @@ rwindow_save(p)
while (i > 0) {
rwdest = rw[i--].rw_in[6];
if (rwdest & 1) {
+ struct rwindow64 rwstack = rw[i];
+
rwdest += BIAS;
- if (copyout((caddr_t)&rw[i], (caddr_t)(u_long)rwdest,
- sizeof(*rw))) {
+ rwstack.rw_in[7] ^= p->p_addr->u_pcb.pcb_wcookie;
+ if (copyout((caddr_t)&rwstack, (caddr_t)(u_long)rwdest,
+ sizeof(rwstack))) {
return (-1);
}
} else {
diff --git a/sys/arch/sparc64/sparc64/vm_machdep.c b/sys/arch/sparc64/sparc64/vm_machdep.c
index a5dcebf5307..0feadd45b6d 100644
--- a/sys/arch/sparc64/sparc64/vm_machdep.c
+++ b/sys/arch/sparc64/sparc64/vm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_machdep.c,v 1.10 2004/05/23 06:46:09 deraadt Exp $ */
+/* $OpenBSD: vm_machdep.c,v 1.11 2005/03/29 19:34:07 kettenis Exp $ */
/* $NetBSD: vm_machdep.c,v 1.38 2001/06/30 00:02:20 eeh Exp $ */
/*
@@ -378,6 +378,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 == fpproc) {
savefpstate(p->p_md.md_fpstate);