From 2e455ec2eb447a65f10b3dc929833f6aa19d526e Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Thu, 30 Apr 2020 19:35:12 +0000 Subject: [PATCH] runtime: avoid overflow from linearAlloc Currently linearAlloc manages an exclusive "end" address for the top of its reserved space. While unlikely for a linearAlloc to be allocated with an "end" address hitting the top of the address space, it is possible and could lead to overflow. Avoid overflow by chopping off the last byte from the linearAlloc if it's bumping up against the top of the address space defensively. In practice, this means that if 32-bit platforms map the top of the address space and use the linearAlloc to acquire arenas, the top arena will not be usable. Fixes #35954. Change-Id: I512cddcd34fd1ab15cb6ca92bbf899fc1ef22ff6 Reviewed-on: https://go-review.googlesource.com/c/go/+/231338 Run-TryBot: Michael Knyszek TryBot-Result: Gobot Gobot Reviewed-by: Austin Clements --- src/runtime/malloc.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 2da694d14a..0fbf45f897 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -604,7 +604,7 @@ func mallocinit() { a, size := sysReserveAligned(unsafe.Pointer(p), arenaSize, heapArenaBytes) if a != nil { mheap_.arena.init(uintptr(a), size) - p = uintptr(a) + size // For hint below + p = mheap_.arena.end // For hint below break } } @@ -1423,6 +1423,13 @@ type linearAlloc struct { } func (l *linearAlloc) init(base, size uintptr) { + if base+size < base { + // Chop off the last byte. The runtime isn't prepared + // to deal with situations where the bounds could overflow. + // Leave that memory reserved, though, so we don't map it + // later. + size -= 1 + } l.next, l.mapped = base, base l.end = base + size } -- 2.50.0