]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: avoid overflow from linearAlloc
authorMichael Anthony Knyszek <mknyszek@google.com>
Thu, 30 Apr 2020 19:35:12 +0000 (19:35 +0000)
committerMichael Knyszek <mknyszek@google.com>
Thu, 7 May 2020 21:40:09 +0000 (21:40 +0000)
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>
src/runtime/malloc.go

index 2da694d14a837032b7030b7894a6b7c592f883d4..0fbf45f897725dee4908cd01a1d3af13f0c5c102 100644 (file)
@@ -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
 }