components/golang/patches/0009-release-branch.go1.5-cmd-compile-fix-uninitialized-m.patch
changeset 5331 9c955076ffe3
equal deleted inserted replaced
5330:c36e3195e3e9 5331:9c955076ffe3
       
     1 From e4e59921f1cc11e60f0096bcb4d54dd683270821 Mon Sep 17 00:00:00 2001
       
     2 From: Austin Clements <[email protected]>
       
     3 Date: Mon, 24 Aug 2015 13:35:49 -0400
       
     4 Subject: [PATCH 09/63] [release-branch.go1.5] cmd/compile: fix uninitialized
       
     5  memory in compare of interface value
       
     6 
       
     7 A comparison of the form l == r where l is an interface and r is
       
     8 concrete performs a type assertion on l to convert it to r's type.
       
     9 However, the compiler fails to zero the temporary where the result of
       
    10 the type assertion is written, so if the type is a pointer type and a
       
    11 stack scan occurs while in the type assertion, it may see an invalid
       
    12 pointer on the stack.
       
    13 
       
    14 Fix this by zeroing the temporary. This is equivalent to the fix for
       
    15 type switches from c4092ac.
       
    16 
       
    17 Fixes #12253.
       
    18 
       
    19 Change-Id: Iaf205d456b856c056b317b4e888ce892f0c555b9
       
    20 Reviewed-on: https://go-review.googlesource.com/13872
       
    21 Reviewed-by: Russ Cox <[email protected]>
       
    22 Reviewed-on: https://go-review.googlesource.com/14242
       
    23 Reviewed-by: Austin Clements <[email protected]>
       
    24 ---
       
    25  src/cmd/compile/internal/gc/walk.go |  5 +++++
       
    26  src/runtime/export_test.go          |  1 +
       
    27  src/runtime/gc_test.go              | 17 +++++++++++++++++
       
    28  src/runtime/iface.go                |  5 +++++
       
    29  4 files changed, 28 insertions(+)
       
    30 
       
    31 diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
       
    32 index ce73018..af3e1cc 100644
       
    33 --- a/src/cmd/compile/internal/gc/walk.go
       
    34 +++ b/src/cmd/compile/internal/gc/walk.go
       
    35 @@ -3219,6 +3219,11 @@ func walkcompare(np **Node, init **NodeList) {
       
    36  
       
    37  	if l != nil {
       
    38  		x := temp(r.Type)
       
    39 +		if haspointers(r.Type) {
       
    40 +			a := Nod(OAS, x, nil)
       
    41 +			typecheck(&a, Etop)
       
    42 +			*init = list(*init, a)
       
    43 +		}
       
    44  		ok := temp(Types[TBOOL])
       
    45  
       
    46  		// l.(type(r))
       
    47 diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
       
    48 index 16d5476..f14dc30 100644
       
    49 --- a/src/runtime/export_test.go
       
    50 +++ b/src/runtime/export_test.go
       
    51 @@ -154,3 +154,4 @@ func BenchSetType(n int, x interface{}) {
       
    52  const PtrSize = ptrSize
       
    53  
       
    54  var TestingAssertE2I2GC = &testingAssertE2I2GC
       
    55 +var TestingAssertE2T2GC = &testingAssertE2T2GC
       
    56 diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go
       
    57 index 636e524..6c9b314 100644
       
    58 --- a/src/runtime/gc_test.go
       
    59 +++ b/src/runtime/gc_test.go
       
    60 @@ -469,3 +469,20 @@ func testAssertVar(x interface{}) error {
       
    61  	}
       
    62  	return nil
       
    63  }
       
    64 +
       
    65 +func TestAssertE2T2Liveness(t *testing.T) {
       
    66 +	*runtime.TestingAssertE2T2GC = true
       
    67 +	defer func() {
       
    68 +		*runtime.TestingAssertE2T2GC = false
       
    69 +	}()
       
    70 +
       
    71 +	poisonStack()
       
    72 +	testIfaceEqual(io.EOF)
       
    73 +}
       
    74 +
       
    75 +func testIfaceEqual(x interface{}) {
       
    76 +	if x == "abc" {
       
    77 +		// Prevent inlining
       
    78 +		panic("")
       
    79 +	}
       
    80 +}
       
    81 diff --git a/src/runtime/iface.go b/src/runtime/iface.go
       
    82 index abd7068..332b7d5 100644
       
    83 --- a/src/runtime/iface.go
       
    84 +++ b/src/runtime/iface.go
       
    85 @@ -229,8 +229,13 @@ func assertE2T(t *_type, e interface{}, r unsafe.Pointer) {
       
    86  	}
       
    87  }
       
    88  
       
    89 +var testingAssertE2T2GC bool
       
    90 +
       
    91  // The compiler ensures that r is non-nil.
       
    92  func assertE2T2(t *_type, e interface{}, r unsafe.Pointer) bool {
       
    93 +	if testingAssertE2T2GC {
       
    94 +		GC()
       
    95 +	}
       
    96  	ep := (*eface)(unsafe.Pointer(&e))
       
    97  	if ep._type != t {
       
    98  		memclr(r, uintptr(t.size))
       
    99 -- 
       
   100 2.6.1
       
   101