• Austin Clements's avatar
    [release-branch.go1.8] runtime: don't corrupt arena bounds on low mmap · a43c0d2d
    Austin Clements authored
    Cherry-pick of CL 43870.
    
    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/43954
    Run-TryBot: Austin Clements <austin@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarChris Broadfoot <cbro@golang.org>
    a43c0d2d
malloc.go 31.4 KB