diff options
| author | Austin Clements <austin@google.com> | 2015-11-15 23:13:16 -0500 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2015-11-16 17:32:40 +0000 |
| commit | 0de59c27ebda76d3e5121888acca304e49009266 (patch) | |
| tree | b447f6fd4ee7ccac4e86f851114b5ee91584a0bb /src/runtime/malloc.go | |
| parent | 97dc591534e580ede4c6145456dadf1e009f1bea (diff) | |
| download | go-0de59c27ebda76d3e5121888acca304e49009266.tar.xz | |
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>
Diffstat (limited to 'src/runtime/malloc.go')
| -rw-r--r-- | src/runtime/malloc.go | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 8ce420a653..d9f52399b8 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -404,7 +404,7 @@ func (h *mheap) sysAlloc(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 |
