Commit 3f7a3240 authored by Adam Langley's avatar Adam Langley

runtime: warn about SELinux based mmap failures on Linux.

SELinux will cause mmap to fail when we request w+x memory unless the
user has configured their policies. We have a warning in make.bash,
but it's quite likely that the policy will be reset at some point and
then all their binaries start failing.

This patch prints a warning on Linux when mmap fails with EACCES.

R=rsc
CC=golang-dev
https://golang.org/cl/152086
parent 593ccd1d
...@@ -69,8 +69,9 @@ TEXT runtime·mmap(SB),7,$0 ...@@ -69,8 +69,9 @@ TEXT runtime·mmap(SB),7,$0
SHRL $12, BP SHRL $12, BP
INT $0x80 INT $0x80
CMPL AX, $0xfffff001 CMPL AX, $0xfffff001
JLS 2(PC) JLS 3(PC)
INT $3 NOTL AX
INCL AX
RET RET
// int32 futex(int32 *uaddr, int32 op, int32 val, // int32 futex(int32 *uaddr, int32 op, int32 val,
......
...@@ -81,8 +81,9 @@ TEXT runtime·mmap(SB),7,$0-32 ...@@ -81,8 +81,9 @@ TEXT runtime·mmap(SB),7,$0-32
MOVL $9, AX // syscall entry MOVL $9, AX // syscall entry
SYSCALL SYSCALL
CMPQ AX, $0xfffffffffffff001 CMPQ AX, $0xfffffffffffff001
JLS 2(PC) JLS 3(PC)
CALL notok(SB) NOTQ AX
INCQ AX
RET RET
TEXT notok(SB),7,$0 TEXT notok(SB),7,$0
......
...@@ -208,8 +208,19 @@ mallocinit(void) ...@@ -208,8 +208,19 @@ mallocinit(void)
void* void*
SysAlloc(uintptr n) SysAlloc(uintptr n)
{ {
void *p;
mstats.sys += n; mstats.sys += n;
return runtime_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); p = runtime_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
if(p < (void*)4096) {
if(p == (void*)EACCES) {
printf("mmap: access denied\n");
printf("If you're running SELinux, enable execmem for this process.\n");
} else {
printf("mmap: errno=%p\n", p);
}
exit(2);
}
return p;
} }
void void
......
...@@ -20,6 +20,10 @@ brk(uint32 n) ...@@ -20,6 +20,10 @@ brk(uint32 n)
byte *v; byte *v;
v = runtime_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); v = runtime_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
if(v < (void *)4096) {
printf("mmap: errno=%p\n", v);
exit(2);
}
m->mem.nmmap += n; m->mem.nmmap += n;
return v; return v;
} }
...@@ -56,6 +60,9 @@ oldmal(uint32 n) ...@@ -56,6 +60,9 @@ oldmal(uint32 n)
m->mem.hunk = m->mem.hunk =
runtime_mmap(nil, NHUNK, PROT_READ|PROT_WRITE|PROT_EXEC, runtime_mmap(nil, NHUNK, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_ANON|MAP_PRIVATE, 0, 0); MAP_ANON|MAP_PRIVATE, 0, 0);
if(m->mem.hunk < (void*)4096) {
*(uint32*)0xf1 = 0;
}
m->mem.nhunk = NHUNK; m->mem.nhunk = NHUNK;
m->mem.nmmap += NHUNK; m->mem.nmmap += NHUNK;
} }
......
...@@ -446,6 +446,13 @@ void notewakeup(Note*); ...@@ -446,6 +446,13 @@ void notewakeup(Note*);
#define runtime_setcallerpc runtime·setcallerpc #define runtime_setcallerpc runtime·setcallerpc
#endif #endif
/*
* This is consistent across Linux and BSD.
* If a new OS is added that is different, move this to
* $GOOS/$GOARCH/defs.h.
*/
#define EACCES 13
/* /*
* low level go-called * low level go-called
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment