diff options
author | Keith Randall <khr@golang.org> | 2021-09-15 09:56:09 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2021-10-15 18:07:49 +0000 |
commit | 8331f25e96d6120bb0ec212bd03abcae53282769 (patch) | |
tree | 28214cd8c99d41a8f1e1de8c384f605c2477c09e /src/reflect/all_test.go | |
parent | 8c99421f01aca303240a8f809bc65fa0c56db861 (diff) | |
download | go-8331f25e96d6120bb0ec212bd03abcae53282769.tar.gz go-8331f25e96d6120bb0ec212bd03abcae53282769.zip |
reflect: make Elem panic on bad notinheap pointers
This CL fixes the subtle issue that Elem can promote a
not-in-heap pointer, which could be any bit pattern, into an
unsafe.Pointer, which the garbage collector can see. If that
resulting value is bad, it can crash the GC.
Make sure that we don't introduce bad pointers that way. We can
make Elem() panic, because any such bad pointers are in the Go heap,
and not-in-heap pointers are not allowed to point into the Go heap.
Update #48399
Change-Id: Ieaf35a611b16b4dfb5e907e229ed4a2aed30e18c
Reviewed-on: https://go-review.googlesource.com/c/go/+/350153
Trust: Keith Randall <khr@golang.org>
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/reflect/all_test.go')
-rw-r--r-- | src/reflect/all_test.go | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 427855b02e..8642d60f8b 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -7697,3 +7697,23 @@ func TestSetIter(t *testing.T) { t.Errorf("pointer incorrect: got %d want %d", got, b) } } + +//go:notinheap +type nih struct{ x int } + +var global_nih = nih{x: 7} + +func TestNotInHeapDeref(t *testing.T) { + // See issue 48399. + v := ValueOf((*nih)(nil)) + v.Elem() + shouldPanic("reflect: call of reflect.Value.Field on zero Value", func() { v.Elem().Field(0) }) + + v = ValueOf(&global_nih) + if got := v.Elem().Field(0).Int(); got != 7 { + t.Fatalf("got %d, want 7", got) + } + + v = ValueOf((*nih)(unsafe.Pointer(new(int)))) + shouldPanic("reflect: reflect.Value.Elem on an invalid notinheap pointer", func() { v.Elem() }) +} |