aboutsummaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2020-06-18 12:51:35 -0700
committerKeith Randall <khr@golang.org>2020-06-19 02:11:35 +0000
commit3dec253783e1211989102ac6abd34cddbf8ba0e6 (patch)
tree5cd7c7bfc7210a64b44a50c9ec543db2550bf552 /src/reflect
parenta07e28194a05800215efe192d2ff840f339924f0 (diff)
downloadgo-3dec253783e1211989102ac6abd34cddbf8ba0e6.tar.gz
go-3dec253783e1211989102ac6abd34cddbf8ba0e6.zip
reflect: zero stack slots before writing to them with write barriers
reflect.assignTo writes to the target using write barriers. Make sure that the memory it is writing to is zeroed, so the write barrier does not read pointers from uninitialized memory. Fixes #39541 Change-Id: Ia64b2cacc193bffd0c1396bbce1dfb8182d4905b Reviewed-on: https://go-review.googlesource.com/c/go/+/238760 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/type.go1
-rw-r--r--src/reflect/value.go8
2 files changed, 9 insertions, 0 deletions
diff --git a/src/reflect/type.go b/src/reflect/type.go
index ec26bef091..38b1283d42 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -3068,6 +3068,7 @@ func ifaceIndir(t *rtype) bool {
return t.kind&kindDirectIface == 0
}
+// Note: this type must agree with runtime.bitvector.
type bitVector struct {
n uint32 // number of bits
data []byte
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 8ce495a33b..c6f24a5609 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -589,6 +589,13 @@ func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool) {
// Convert v to type typ if v is assignable to a variable
// of type t in the language spec.
// See issue 28761.
+ if typ.Kind() == Interface {
+ // We must clear the destination before calling assignTo,
+ // in case assignTo writes (with memory barriers) to the
+ // target location used as scratch space. See issue 39541.
+ *(*uintptr)(addr) = 0
+ *(*uintptr)(add(addr, ptrSize, "typ.size == 2*ptrSize")) = 0
+ }
v = v.assignTo("reflect.MakeFunc", typ, addr)
// We are writing to stack. No write barrier.
@@ -2381,6 +2388,7 @@ func NewAt(typ Type, p unsafe.Pointer) Value {
// assignTo returns a value v that can be assigned directly to typ.
// It panics if v is not assignable to typ.
// For a conversion to an interface type, target is a suggested scratch space to use.
+// target must be initialized memory (or nil).
func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
if v.flag&flagMethod != 0 {
v = makeMethodValue(context, v)