From: Gustavo Niemeyer Date: Wed, 15 Feb 2012 00:09:02 +0000 (-0200) Subject: runtime: fix grsec support X-Git-Tag: weekly.2012-02-14~13 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8eee153bc81680a6115dc8e1f2661ee51d5c7383;p=gostls13.git runtime: fix grsec support Changeset 36c9c7810f14 broke support for grsec-patched kernels. Those do not give back the address requested without MAP_FIXED, so when verifying an mmap without this flag for success, the resulting address must not be compared against the requested address since it may have succeeded at a different location. R=golang-dev, rsc, gustavo, iant CC=golang-dev https://golang.org/cl/5650072 --- diff --git a/src/pkg/runtime/mem_linux.c b/src/pkg/runtime/mem_linux.c index 47287939ad..b3e79cc412 100644 --- a/src/pkg/runtime/mem_linux.c +++ b/src/pkg/runtime/mem_linux.c @@ -34,6 +34,21 @@ addrspace_free(void *v, uintptr n) return 1; } +static void * +mmap_fixed(byte *v, uintptr n, int32 prot, int32 flags, int32 fd, uint32 offset) +{ + void *p; + + p = runtime·mmap(v, n, prot, flags, fd, offset); + if(p != v && addrspace_free(v, n)) { + // On some systems, mmap ignores v without + // MAP_FIXED, so retry if the address space is free. + if(p > (void*)4096) + runtime·munmap(p, n); + p = runtime·mmap(v, n, prot, flags|MAP_FIXED, fd, offset); + } + return p; +} void* runtime·SysAlloc(uintptr n) @@ -76,20 +91,16 @@ runtime·SysReserve(void *v, uintptr n) // if we can reserve at least 64K and check the assumption in SysMap. // Only user-mode Linux (UML) rejects these requests. if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) { - p = runtime·mmap(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); - if (p != v) { + p = mmap_fixed(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); + if (p != v) return nil; - } runtime·munmap(p, 64<<10); - - return v; } p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); - if((uintptr)p < 4096 || -(uintptr)p < 4096) { + if((uintptr)p < 4096 || -(uintptr)p < 4096) return nil; - } return p; } @@ -102,15 +113,7 @@ runtime·SysMap(void *v, uintptr n) // On 64-bit, we don't actually have v reserved, so tread carefully. if(sizeof(void*) == 8 && (uintptr)v >= 0xffffffffU) { - p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); - if(p != v && addrspace_free(v, n)) { - // On some systems, mmap ignores v without - // MAP_FIXED, so retry if the address space is free. - if(p > (void*)4096) { - runtime·munmap(p, n); - } - p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0); - } + p = mmap_fixed(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); if(p == (void*)ENOMEM) runtime·throw("runtime: out of memory"); if(p != v) {