1
0
mirror of https://github.com/golang/go synced 2024-11-23 19:40:08 -07:00

runtime: avoid overflow in (*mheap).grow

Currently when checking if we can grow the heap into the current arena,
we do an addition which may overflow. This is particularly likely on
32-bit systems.

Avoid this situation by explicitly checking for overflow, and adding in
some comments about when overflow is possible, when it isn't, and why.

For #35954.

Change-Id: I2d4ecbb1ccbd43da55979cc721f0cd8d1757add2
Reviewed-on: https://go-review.googlesource.com/c/go/+/231337
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Michael Anthony Knyszek 2020-05-06 19:18:07 +00:00 committed by Michael Knyszek
parent f9640b88c7
commit 14ae846f54

View File

@ -1327,8 +1327,11 @@ func (h *mheap) grow(npage uintptr) bool {
ask := alignUp(npage, pallocChunkPages) * pageSize ask := alignUp(npage, pallocChunkPages) * pageSize
totalGrowth := uintptr(0) totalGrowth := uintptr(0)
nBase := alignUp(h.curArena.base+ask, physPageSize) // This may overflow because ask could be very large
if nBase > h.curArena.end { // and is otherwise unrelated to h.curArena.base.
end := h.curArena.base + ask
nBase := alignUp(end, physPageSize)
if nBase > h.curArena.end || /* overflow */ end < h.curArena.base {
// Not enough room in the current arena. Allocate more // Not enough room in the current arena. Allocate more
// arena space. This may not be contiguous with the // arena space. This may not be contiguous with the
// current arena, so we have to request the full ask. // current arena, so we have to request the full ask.
@ -1364,7 +1367,10 @@ func (h *mheap) grow(npage uintptr) bool {
mSysStatInc(&memstats.heap_released, asize) mSysStatInc(&memstats.heap_released, asize)
mSysStatInc(&memstats.heap_idle, asize) mSysStatInc(&memstats.heap_idle, asize)
// Recalculate nBase // Recalculate nBase.
// We know this won't overflow, because sysAlloc returned
// a valid region starting at h.curArena.base which is at
// least ask bytes in size.
nBase = alignUp(h.curArena.base+ask, physPageSize) nBase = alignUp(h.curArena.base+ask, physPageSize)
} }