]> Cypherpunks repositories - gostls13.git/commit
runtime: don't corrupt arena bounds on low mmap
authorAustin Clements <austin@google.com>
Mon, 22 May 2017 19:53:49 +0000 (15:53 -0400)
committerAustin Clements <austin@google.com>
Tue, 23 May 2017 15:23:21 +0000 (15:23 +0000)
commite5a5c03f5bc9cae965d3e6e625fe7ac3726b0ff4
tree736c5f3b645ecfe4e11520d7b1c47d4c0ae8b93f
parent95d991d30c59edc4943bd8baf5c664c5f8b1cebe
runtime: don't corrupt arena bounds on low mmap

If mheap.sysAlloc doesn't have room in the heap arena for an
allocation, it will attempt to map more address space with sysReserve.
sysReserve is given a hint, but can return any unused address range.
Currently, mheap.sysAlloc incorrectly assumes the returned region will
never fall between arena_start and arena_used. If it does,
mheap.sysAlloc will blindly accept the new region as the new
arena_used and arena_end, causing these to decrease and make it so any
Go heap above the new arena_used is no longer considered part of the
Go heap. This assumption *used to be* safe because we had all memory
between arena_start and arena_used mapped, but when we switched to an
arena_start of 0 on 32-bit, it became no longer safe.

Most likely, we've only recently seen this bug occur because we
usually start arena_used just above the binary, which is low in the
address space. Hence, the kernel is very unlikely to give us a region
before arena_used.

Since mheap.sysAlloc is a linear allocator, there's not much we can do
to handle this well. Hence, we fix this problem by simply rejecting
the new region if it isn't after arena_end. In this case, we'll take
the fall-back path and mmap a small region at any address just for the
requested memory.

Fixes #20259.

Change-Id: Ib72e8cd621545002d595c7cade1e817cfe3e5b1e
Reviewed-on: https://go-review.googlesource.com/43870
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/malloc.go