aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mbitmap.go
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2022-11-09 10:55:54 -0500
committerCherry Mui <cherryyz@google.com>2022-11-15 02:55:24 +0000
commitfebe7b8e2a4dd7cce6ab8d02cf79a5430819cbe5 (patch)
tree6addd3f3cfccb872192983c2ef4a578bce9a39b3 /src/runtime/mbitmap.go
parentd52883f443e1d564b0300acdd382af1769bf0477 (diff)
downloadgo-febe7b8e2a4dd7cce6ab8d02cf79a5430819cbe5.tar.xz
runtime: make GC see object as allocated after it is initialized
When the GC is scanning some memory (possibly conservatively), finding a pointer, while concurrently another goroutine is allocating an object at the same address as the found pointer, the GC may see the pointer before the object and/or the heap bits are initialized. This may cause the GC to see bad pointers and possibly crash. To prevent this, we make it that the scanner can only see the object as allocated after the object and the heap bits are initialized. Currently the allocator uses freeindex to find the next available slot, and that code is coupled with updating the free index to a new slot past it. The scanner also uses the freeindex to determine if an object is allocated. This is somewhat racy. This CL makes the scanner use a different field, which is only updated after the object initialization (and a memory barrier). Fixes #54596. Change-Id: I2a57a226369926e7192c253dd0d21d3faf22297c Reviewed-on: https://go-review.googlesource.com/c/go/+/449017 Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/runtime/mbitmap.go')
-rw-r--r--src/runtime/mbitmap.go2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go
index dc99ba768b..088b566729 100644
--- a/src/runtime/mbitmap.go
+++ b/src/runtime/mbitmap.go
@@ -191,7 +191,7 @@ func (s *mspan) nextFreeIndex() uintptr {
// been no preemption points since ensuring this (which could allow a
// GC transition, which would allow the state to change).
func (s *mspan) isFree(index uintptr) bool {
- if index < s.freeindex {
+ if index < s.freeIndexForScan {
return false
}
bytep, mask := s.allocBits.bitp(index)