aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/malloc.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2020-04-30 19:35:12 +0000
committerMichael Knyszek <mknyszek@google.com>2020-05-07 21:40:09 +0000
commit2e455ec2eb447a65f10b3dc929833f6aa19d526e (patch)
tree7379652b18ad4d67b9750dee4372445581752f78 /src/runtime/malloc.go
parent14ae846f54c105f4d48f1afa5aa5446e4b9e7cdc (diff)
downloadgo-2e455ec2eb447a65f10b3dc929833f6aa19d526e.tar.gz
go-2e455ec2eb447a65f10b3dc929833f6aa19d526e.zip
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 <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/malloc.go')
-rw-r--r--src/runtime/malloc.go9
1 files changed, 8 insertions, 1 deletions
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
}