Skip to content

Commit

Permalink
[release-branch.go1.23] runtime: explicitly keep handle alive during …
Browse files Browse the repository at this point in the history
…getOrAddWeakHandle

getOrAddWeakHandle is very careful about keeping its input alive across
the operation, but not very careful about keeping the heap-allocated
handle it creates alive. In fact, there's a window in this function
where it is *only* visible via the special. Specifically, the window of
time between when the handle is stored in the special and when the
special actually becomes visible to the GC.

(If we fail to add the special because it already exists, that case is
fine. We don't even use the same handle value, but the one we obtain
from the attached GC-visible special, *and* we return that value, so it
remains live.)

For #70455.
Fixes #70469.

Change-Id: Iadaff0cfb93bcaf61ba2b05be7fa0519c481de82
Reviewed-on: https://go-review.googlesource.com/c/go/+/630316
Auto-Submit: Michael Knyszek <[email protected]>
Reviewed-by: Cherry Mui <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
  • Loading branch information
mknyszek authored and gopherbot committed Nov 20, 2024
1 parent d8adc6c commit be062b7
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/runtime/mheap.go
Original file line number Diff line number Diff line change
Expand Up @@ -2172,8 +2172,14 @@ func getOrAddWeakHandle(p unsafe.Pointer) *atomic.Uintptr {

// Keep p alive for the duration of the function to ensure
// that it cannot die while we're trying to do this.
//
// Same for handle, which is only stored in the special.
// There's a window where it might die if we don't keep it
// alive explicitly. Returning it here is probably good enough,
// but let's be defensive and explicit. See #70455.
KeepAlive(p)
return s.handle
KeepAlive(handle)
return handle
}

// There was an existing handle. Free the special
Expand All @@ -2193,7 +2199,10 @@ func getOrAddWeakHandle(p unsafe.Pointer) *atomic.Uintptr {

// Keep p alive for the duration of the function to ensure
// that it cannot die while we're trying to do this.
//
// Same for handle, just to be defensive.
KeepAlive(p)
KeepAlive(handle)
return handle
}

Expand Down

0 comments on commit be062b7

Please sign in to comment.