From db56a63547d7ae9f19afd2497c67f717154f9115 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 3 Oct 2016 14:45:52 -0400 Subject: [PATCH] runtime: avoid write barriers to uninitialized finalizer frame memory 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 --- src/runtime/mfinal.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go index 4f3e887bc8..dae3956cd1 100644 --- a/src/runtime/mfinal.go +++ b/src/runtime/mfinal.go @@ -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