Commit e4e59921 authored by Austin Clements's avatar Austin Clements Committed by Andrew Gerrand

[release-branch.go1.5] cmd/compile: fix uninitialized memory in compare of interface value

A comparison of the form l == r where l is an interface and r is
concrete performs a type assertion on l to convert it to r's type.
However, the compiler fails to zero the temporary where the result of
the type assertion is written, so if the type is a pointer type and a
stack scan occurs while in the type assertion, it may see an invalid
pointer on the stack.

Fix this by zeroing the temporary. This is equivalent to the fix for
type switches from c4092ac3.

Fixes #12253.

Change-Id: Iaf205d456b856c056b317b4e888ce892f0c555b9
Reviewed-on: https://go-review.googlesource.com/13872Reviewed-by: default avatarRuss Cox <rsc@golang.org>
Reviewed-on: https://go-review.googlesource.com/14242Reviewed-by: default avatarAustin Clements <austin@google.com>
parent 13d03fae
......@@ -3219,6 +3219,11 @@ func walkcompare(np **Node, init **NodeList) {
if l != nil {
x := temp(r.Type)
if haspointers(r.Type) {
a := Nod(OAS, x, nil)
typecheck(&a, Etop)
*init = list(*init, a)
}
ok := temp(Types[TBOOL])
// l.(type(r))
......
......@@ -154,3 +154,4 @@ func BenchSetType(n int, x interface{}) {
const PtrSize = ptrSize
var TestingAssertE2I2GC = &testingAssertE2I2GC
var TestingAssertE2T2GC = &testingAssertE2T2GC
......@@ -469,3 +469,20 @@ func testAssertVar(x interface{}) error {
}
return nil
}
func TestAssertE2T2Liveness(t *testing.T) {
*runtime.TestingAssertE2T2GC = true
defer func() {
*runtime.TestingAssertE2T2GC = false
}()
poisonStack()
testIfaceEqual(io.EOF)
}
func testIfaceEqual(x interface{}) {
if x == "abc" {
// Prevent inlining
panic("")
}
}
......@@ -229,8 +229,13 @@ func assertE2T(t *_type, e interface{}, r unsafe.Pointer) {
}
}
var testingAssertE2T2GC bool
// The compiler ensures that r is non-nil.
func assertE2T2(t *_type, e interface{}, r unsafe.Pointer) bool {
if testingAssertE2T2GC {
GC()
}
ep := (*eface)(unsafe.Pointer(&e))
if ep._type != t {
memclr(r, uintptr(t.size))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment