Skip to content

Commit bdd4b95

Browse files
4a6f656cbradfitz
authored andcommitted
[release-branch.go1.4] runtime: mark stacks with MAP_STACK on openbsd
OpenBSD 6.4+ requires that stack regions be marked with MAP_STACK. MAP_STACK is permitted (but is a no-op) on OpenBSD 6.3. Change-Id: I8118f27e6a0feb97ae570cbc8aad461ec20676fa Reviewed-on: https://go-review.googlesource.com/c/154477 Run-TryBot: Brad Fitzpatrick <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 182bdbb commit bdd4b95

File tree

6 files changed

+43
-1
lines changed

6 files changed

+43
-1
lines changed

src/runtime/defs_openbsd_386.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ enum {
1414
MAP_ANON = 0x1000,
1515
MAP_PRIVATE = 0x2,
1616
MAP_FIXED = 0x10,
17+
MAP_STACK = 0x4000,
1718

1819
MADV_FREE = 0x6,
1920

src/runtime/defs_openbsd_amd64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ enum {
1414
MAP_ANON = 0x1000,
1515
MAP_PRIVATE = 0x2,
1616
MAP_FIXED = 0x10,
17+
MAP_STACK = 0x4000,
1718

1819
MADV_FREE = 0x6,
1920

src/runtime/malloc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ struct MLink
197197
// if accessed. Used only for debugging the runtime.
198198

199199
void* runtime·sysAlloc(uintptr nbytes, uint64 *stat);
200+
void runtime·sysMarkStack(void *v, uintptr nbytes);
201+
void runtime·sysUnmarkStack(void *v, uintptr nbytes);
200202
void runtime·SysFree(void *v, uintptr nbytes, uint64 *stat);
201203
void runtime·SysUnused(void *v, uintptr nbytes);
202204
void runtime·SysUsed(void *v, uintptr nbytes);

src/runtime/mem_openbsd.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,29 @@ runtime·sysAlloc(uintptr n, uint64 *stat)
2727
return v;
2828
}
2929

30+
#pragma textflag NOSPLIT
31+
void
32+
runtime·sysMarkStack(void *v, uintptr n)
33+
{
34+
void *p;
35+
36+
// Stack regions on OpenBSD 6.4+ must be marked with MAP_STACK.
37+
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_FIXED|MAP_STACK, -1, 0);
38+
if (p == ((void *)-1) || p != v)
39+
runtime·throw("runtime: failed to mark stack");
40+
}
41+
42+
#pragma textflag NOSPLIT
43+
void
44+
runtime·sysUnmarkStack(void *v, uintptr n)
45+
{
46+
void *p;
47+
48+
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
49+
if (p == ((void *)-1) || p != v)
50+
runtime·throw("runtime: failed to unmark stack");
51+
}
52+
3053
void
3154
runtime·SysUnused(void *v, uintptr n)
3255
{

src/runtime/os_openbsd.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,10 @@ runtime·newosproc(M *mp, void *stk)
167167

168168
param.tf_tcb = (byte*)&mp->tls[0];
169169
param.tf_tid = (int32*)&mp->procid;
170-
param.tf_stack = stk;
170+
171+
// Stack pointer must point inside stack area (as marked with MAP_STACK),
172+
// rather than at the top of it.
173+
param.tf_stack = (void*)((uintptr)stk - sizeof(uintptr));
171174

172175
oset = runtime·sigprocmask(SIG_SETMASK, sigset_all);
173176
ret = runtime·tfork(&param, sizeof(param), mp, mp->g0, runtime·mstart);

src/runtime/stack.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ poolalloc(uint8 order)
7171
runtime·throw("bad ref");
7272
if(s->freelist != nil)
7373
runtime·throw("bad freelist");
74+
#ifdef GOOS_openbsd
75+
runtime·sysMarkStack((void *)(s->start << PageShift), s->npages << PageShift);
76+
#endif
7477
for(i = 0; i < StackCacheSize; i += FixedStack << order) {
7578
x = (MLink*)((s->start << PageShift) + i);
7679
x->next = s->freelist;
@@ -110,6 +113,9 @@ poolfree(MLink *x, uint8 order)
110113
// span is completely free - return to heap
111114
runtime·MSpanList_Remove(s);
112115
s->freelist = nil;
116+
#ifdef GOOS_openbsd
117+
runtime·sysUnmarkStack((void *)(s->start << PageShift), s->npages << PageShift);
118+
#endif
113119
runtime·MHeap_FreeStack(&runtime·mheap, s);
114120
}
115121
}
@@ -246,6 +252,9 @@ runtime·stackalloc(uint32 n)
246252
s = runtime·MHeap_AllocStack(&runtime·mheap, ROUND(n, PageSize) >> PageShift);
247253
if(s == nil)
248254
runtime·throw("out of memory");
255+
#ifdef GOOS_openbsd
256+
runtime·sysMarkStack((void *)(s->start << PageShift), s->npages << PageShift);
257+
#endif
249258
v = (byte*)(s->start<<PageShift);
250259
}
251260

@@ -307,6 +316,9 @@ runtime·stackfree(Stack stk)
307316
runtime·printf("%p %p\n", s->start<<PageShift, v);
308317
runtime·throw("bad span state");
309318
}
319+
#ifdef GOOS_openbsd
320+
runtime·sysUnmarkStack((void *)(s->start << PageShift), s->npages << PageShift);
321+
#endif
310322
runtime·MHeap_FreeStack(&runtime·mheap, s);
311323
}
312324
}

0 commit comments

Comments
 (0)