]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: avoid write barriers to uninitialized finalizer frame memory
authorAustin Clements <austin@google.com>
Mon, 3 Oct 2016 18:45:52 +0000 (14:45 -0400)
committerAustin Clements <austin@google.com>
Fri, 28 Oct 2016 19:13:44 +0000 (19:13 +0000)
runfinq allocates a stack frame on the heap for constructing the
finalizer function calls and reuses it for each call. However, because
the type of this frame is constantly shifting, it tells mallocgc there
are no pointers in it and it acts essentially like uninitialized
memory between uses. But runfinq uses pointer writes with write
barriers to "initialize" this memory, which is not going to be safe
with the hybrid barrier, since the hybrid barrier may see a stale
pointer left in the "uninitialized" frame.

Fix this by zero-initializing the argument values in the frame before
writing the argument pointers.

Updates #17503.

Change-Id: I951c0a2be427eb9082a32d65c4410e6fdef041be
Reviewed-on: https://go-review.googlesource.com/31453
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/mfinal.go

index 4f3e887bc842cabac7908963e3c8733d662886f6..dae3956cd17293321a359e679d460e2134179916 100644 (file)
@@ -182,6 +182,11 @@ func runfinq() {
                                if f.fint == nil {
                                        throw("missing type in runfinq")
                                }
+                               // frame is effectively uninitialized
+                               // memory. That means we have to clear
+                               // it before writing to it to avoid
+                               // confusing the write barrier.
+                               *(*[2]uintptr)(frame) = [2]uintptr{}
                                switch f.fint.kind & kindMask {
                                case kindPtr:
                                        // direct use of pointer