summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevon H. O'Dell <devon.odell@gmail.com>2009-12-08 18:19:30 -0800
committerDevon H. O'Dell <devon.odell@gmail.com>2009-12-08 18:19:30 -0800
commit6e2d921ce59c0470793425b459aa2148a7414abb (patch)
tree0d5f66dd4aafdd58ba85c648ea6b3e755a1bbc58
parent437cfade3137080b4884d4b2c19921e4e65b8cc3 (diff)
downloadgolang-6e2d921ce59c0470793425b459aa2148a7414abb.tar.gz
Fix stack on FreeBSD / add stack check across the board
FreeBSD was passing stk as the new thread's stack base, while stk is the top of the stack in go. The added check should cause a trap if this ever comes up in any new ports, or regresses in current ones. R=rsc CC=golang-dev http://codereview.appspot.com/167055 Committer: Russ Cox <rsc@golang.org>
-rw-r--r--src/pkg/runtime/386/asm.s11
-rw-r--r--src/pkg/runtime/amd64/asm.s10
-rw-r--r--src/pkg/runtime/darwin/386/sys.s1
-rw-r--r--src/pkg/runtime/freebsd/386/sys.s17
-rw-r--r--src/pkg/runtime/freebsd/amd64/sys.s1
-rw-r--r--src/pkg/runtime/freebsd/thread.c4
-rw-r--r--src/pkg/runtime/linux/386/sys.s1
-rw-r--r--src/pkg/runtime/linux/amd64/sys.s1
8 files changed, 36 insertions, 10 deletions
diff --git a/src/pkg/runtime/386/asm.s b/src/pkg/runtime/386/asm.s
index bd88f0fdc..7ec62161d 100644
--- a/src/pkg/runtime/386/asm.s
+++ b/src/pkg/runtime/386/asm.s
@@ -323,6 +323,17 @@ TEXT runcgo(SB),7,$16
MOVL 4(SP), SP
RET
+// check that SP is in range [g->stackbase, g->stackguard)
+TEXT stackcheck(SB), 7, $0
+ MOVL g, AX
+ CMPL g_stackbase(AX), SP
+ JHI 2(PC)
+ INT $3
+ CMPL SP, g_stackguard(AX)
+ JHI 2(PC)
+ INT $3
+ RET
+
GLOBL m0(SB), $1024
GLOBL g0(SB), $1024
diff --git a/src/pkg/runtime/amd64/asm.s b/src/pkg/runtime/amd64/asm.s
index aee4e9a3f..3bd63ad15 100644
--- a/src/pkg/runtime/amd64/asm.s
+++ b/src/pkg/runtime/amd64/asm.s
@@ -301,3 +301,13 @@ TEXT runcgo(SB),7,$32
MOVQ 8(SP), SP
RET
+// check that SP is in range [g->stackbase, g->stackguard)
+TEXT stackcheck(SB), 7, $0
+ CMPQ g_stackbase(g), SP
+ JHI 2(PC)
+ INT $3
+ CMPQ SP, g_stackguard(g)
+ JHI 2(PC)
+ INT $3
+ RET
+
diff --git a/src/pkg/runtime/darwin/386/sys.s b/src/pkg/runtime/darwin/386/sys.s
index 445f53002..38459447f 100644
--- a/src/pkg/runtime/darwin/386/sys.s
+++ b/src/pkg/runtime/darwin/386/sys.s
@@ -153,6 +153,7 @@ TEXT bsdthread_start(SB),7,$0
MOVL AX, g
MOVL DX, m
MOVL BX, m_procid(DX) // m->procid = thread port (for debuggers)
+ CALL stackcheck(SB) // smashes AX
CALL CX // fn()
CALL exit1(SB)
RET
diff --git a/src/pkg/runtime/freebsd/386/sys.s b/src/pkg/runtime/freebsd/386/sys.s
index 1c0eaead5..651ccb234 100644
--- a/src/pkg/runtime/freebsd/386/sys.s
+++ b/src/pkg/runtime/freebsd/386/sys.s
@@ -9,13 +9,13 @@
#include "386/asm.h"
TEXT sys_umtx_op(SB),7,$-4
- MOVL $454, AX
- INT $0x80
+ MOVL $454, AX
+ INT $0x80
RET
TEXT thr_new(SB),7,$-4
- MOVL $455, AX
- INT $0x80
+ MOVL $455, AX
+ INT $0x80
RET
TEXT thr_start(SB),7,$0
@@ -33,10 +33,11 @@ TEXT thr_start(SB),7,$0
POPL AX
POPL AX
POPAL
- MOVL BX, g
- MOVL AX, m
- CALL mstart(SB)
- MOVL 0, AX // crash (not reached)
+ MOVL BX, g
+ MOVL AX, m
+ CALL stackcheck(SB) // smashes AX
+ CALL mstart(SB)
+ MOVL 0, AX // crash (not reached)
// Exit the entire program (like C exit)
TEXT exit(SB),7,$-4
diff --git a/src/pkg/runtime/freebsd/amd64/sys.s b/src/pkg/runtime/freebsd/amd64/sys.s
index 1b6246810..30184e297 100644
--- a/src/pkg/runtime/freebsd/amd64/sys.s
+++ b/src/pkg/runtime/freebsd/amd64/sys.s
@@ -28,6 +28,7 @@ TEXT thr_new(SB),7,$0
TEXT thr_start(SB),7,$0
MOVQ DI, m
MOVQ m_g0(m), g
+ CALL stackcheck(SB)
CALL mstart(SB)
MOVQ 0, AX // crash (not reached)
diff --git a/src/pkg/runtime/freebsd/thread.c b/src/pkg/runtime/freebsd/thread.c
index 5f4402236..bf891e980 100644
--- a/src/pkg/runtime/freebsd/thread.c
+++ b/src/pkg/runtime/freebsd/thread.c
@@ -139,8 +139,8 @@ newosproc(M *m, G *g, void *stk, void (*fn)(void))
param.start_func = thr_start;
param.arg = m;
- param.stack_base = stk;
- param.stack_size = g->stackbase - g->stackguard + 256;
+ param.stack_base = (int8*)g->stackbase;
+ param.stack_size = (byte*)stk - (byte*)g->stackbase;
param.child_tid = (intptr*)&m->procid;
param.parent_tid = nil;
param.tls_base = (int8*)&m->tls[0];
diff --git a/src/pkg/runtime/linux/386/sys.s b/src/pkg/runtime/linux/386/sys.s
index 097dfe915..72882cb9d 100644
--- a/src/pkg/runtime/linux/386/sys.s
+++ b/src/pkg/runtime/linux/386/sys.s
@@ -152,6 +152,7 @@ TEXT clone(SB),7,$0
MOVL DX, g
MOVL BX, m
+ CALL stackcheck(SB) // smashes AX
MOVL 0(DX), DX // paranoia; check they are not nil
MOVL 0(BX), BX
diff --git a/src/pkg/runtime/linux/amd64/sys.s b/src/pkg/runtime/linux/amd64/sys.s
index 238a423b1..6565d86de 100644
--- a/src/pkg/runtime/linux/amd64/sys.s
+++ b/src/pkg/runtime/linux/amd64/sys.s
@@ -149,6 +149,7 @@ TEXT clone(SB),7,$0
MOVQ SI, SP
MOVQ R8, m
MOVQ R9, g
+ CALL stackcheck(SB)
// Initialize m->procid to Linux tid
MOVL $186, AX // gettid