Commit db56a635 authored by Austin Clements's avatar Austin Clements

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/31453Reviewed-by: 's avatarRick Hudson <rlh@golang.org>
parent c5e70065
...@@ -182,6 +182,11 @@ func runfinq() { ...@@ -182,6 +182,11 @@ func runfinq() {
if f.fint == nil { if f.fint == nil {
throw("missing type in runfinq") 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 { switch f.fint.kind & kindMask {
case kindPtr: case kindPtr:
// direct use of pointer // direct use of pointer
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment