]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.5] runtime: handle sysReserve returning a pointer below the arena
authorAustin Clements <austin@google.com>
Mon, 16 Nov 2015 04:13:16 +0000 (23:13 -0500)
committerAustin Clements <austin@google.com>
Tue, 17 Nov 2015 02:25:11 +0000 (02:25 +0000)
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>
src/runtime/malloc.go

index a8a5d48b5da8a3600f8b392e6701f6d9d26fd618..b966eed470481c5a88632042766622348738ebf4 100644 (file)
@@ -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