]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix liveness issue in test-only getgcmask
authorMichael Anthony Knyszek <mknyszek@google.com>
Wed, 15 Nov 2023 21:54:45 +0000 (21:54 +0000)
committerMichael Knyszek <mknyszek@google.com>
Thu, 16 Nov 2023 05:48:17 +0000 (05:48 +0000)
getgcmask stops referencing the object passed to it sometime between
when the object is looked up and when the function returns. Notably,
this can happen while the GC mask is actively being produced, and thus
the GC might free the object.

This is easily reproducible by adding a runtime.GC call at just the
right place. Adding a KeepAlive on the heap-object path fixes it.

Fixes #64188.

Change-Id: I5ed4cae862fc780338b60d969fd7fbe896352ce4
Reviewed-on: https://go-review.googlesource.com/c/go/+/542716
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/runtime/mbitmap_allocheaders.go
src/runtime/mbitmap_noallocheaders.go

index 77f5b4c990378b5ab7593c9846ca4be3192c3384..319d71f92fe5a846a33013ef3d043029203b4beb 100644 (file)
@@ -1078,6 +1078,11 @@ func getgcmask(ep any) (mask []byte) {
                for len(mask) > 0 && mask[len(mask)-1] == 0 {
                        mask = mask[:len(mask)-1]
                }
+
+               // Make sure we keep ep alive. We may have stopped referencing
+               // ep's data pointer sometime before this point and it's possible
+               // for that memory to get freed.
+               KeepAlive(ep)
                return
        }
 
index 96c70a09701fb15dd1973375d9d96da7ca20ce5e..dab15889a4fc20384f4e7fd14f00988a4701ab82 100644 (file)
@@ -744,6 +744,11 @@ func getgcmask(ep any) (mask []byte) {
                for len(mask) > 0 && mask[len(mask)-1] == 0 {
                        mask = mask[:len(mask)-1]
                }
+
+               // Make sure we keep ep alive. We may have stopped referencing
+               // ep's data pointer sometime before this point and it's possible
+               // for that memory to get freed.
+               KeepAlive(ep)
                return
        }