aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-11-15 23:13:16 -0500
committerAustin Clements <austin@google.com>2015-11-17 02:25:11 +0000
commita10b27094cbddd7d470281590a50b5b38265e541 (patch)
tree4c632bab86cd574a1353d664cf187e997ab413e6
parente49330911f52bcb2aeb7eae4ca6df4fc8a013abe (diff)
downloadgo-a10b27094cbddd7d470281590a50b5b38265e541.tar.gz
go-a10b27094cbddd7d470281590a50b5b38265e541.zip
[release-branch.go1.5] runtime: handle sysReserve returning a pointer below the arena
In mheap.sysAlloc, if an allocation at arena_used would exceed arena_end (but wouldn't yet push us past arena_start+_MaxArean32), it trie to extend the arena reservation by another 256 MB. It extends the arena by calling sysReserve, which, on 32-bit, calls mmap without MAP_FIXED, which means the address is just a hint and the kernel can put the mapping wherever it wants. In particular, mmap may choose an address below arena_start (the kernel also chose arena_start, so there could be lots of space below it). Currently, we don't detect this case and, if it happens, mheap.sysAlloc will corrupt arena_end and arena_used then return the low pointer to mheap.grow, which will crash when it attempts to index in to h_spans with an underflowed index. Fix this by checking not only that that p+p_size isn't too high, but that p isn't too low. Fixes #13143. Change-Id: I8d0f42bd1484460282a83c6f1a6f8f0df7fb2048 Reviewed-on: https://go-review.googlesource.com/16927 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-on: https://go-review.googlesource.com/16988 Reviewed-by: Russ Cox <rsc@golang.org>
-rw-r--r--src/runtime/malloc.go2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index a8a5d48b5d..b966eed470 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -401,7 +401,7 @@ func mHeap_SysAlloc(h *mheap, n uintptr) unsafe.Pointer {
if p == h.arena_end {
h.arena_end = new_end
h.arena_reserved = reserved
- } else if p+p_size <= h.arena_start+_MaxArena32 {
+ } else if h.arena_start <= p && p+p_size <= h.arena_start+_MaxArena32 {
// Keep everything page-aligned.
// Our pages are bigger than hardware pages.
h.arena_end = p + p_size