1// run 2 3// Copyright 2011 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7// Test that the implementation catches nil ptr indirection 8// in a large address space. 9 10// Address space starts at 1<<32 on AIX and on darwin/arm64 and on windows/arm64, so dummy is too far. 11//go:build !aix && (!darwin || !arm64) && (!windows || !arm64) 12 13package main 14 15import "unsafe" 16 17// Having a big address space means that indexing 18// at a 256 MB offset from a nil pointer might not 19// cause a memory access fault. This test checks 20// that Go is doing the correct explicit checks to catch 21// these nil pointer accesses, not just relying on the hardware. 22var dummy [256 << 20]byte // give us a big address space 23 24func main() { 25 // the test only tests what we intend to test 26 // if dummy starts in the first 256 MB of memory. 27 // otherwise there might not be anything mapped 28 // at the address that might be accidentally 29 // dereferenced below. 30 if uintptr(unsafe.Pointer(&dummy)) > 256<<20 { 31 panic("dummy too far out") 32 } 33 34 shouldPanic(p1) 35 shouldPanic(p2) 36 shouldPanic(p3) 37 shouldPanic(p4) 38 shouldPanic(p5) 39 shouldPanic(p6) 40 shouldPanic(p7) 41 shouldPanic(p8) 42 shouldPanic(p9) 43 shouldPanic(p10) 44 shouldPanic(p11) 45 shouldPanic(p12) 46 shouldPanic(p13) 47 shouldPanic(p14) 48 shouldPanic(p15) 49 shouldPanic(p16) 50} 51 52func shouldPanic(f func()) { 53 defer func() { 54 if recover() == nil { 55 panic("memory reference did not panic") 56 } 57 }() 58 f() 59} 60 61func p1() { 62 // Array index. 63 var p *[1 << 30]byte = nil 64 println(p[256<<20]) // very likely to be inside dummy, but should panic 65} 66 67var xb byte 68 69func p2() { 70 var p *[1 << 30]byte = nil 71 xb = 123 72 73 // Array index. 74 println(p[uintptr(unsafe.Pointer(&xb))]) // should panic 75} 76 77func p3() { 78 // Array to slice. 79 var p *[1 << 30]byte = nil 80 var x []byte = p[0:] // should panic 81 _ = x 82} 83 84var q *[1 << 30]byte 85 86func p4() { 87 // Array to slice. 88 var x []byte 89 var y = &x 90 *y = q[0:] // should crash (uses arraytoslice runtime routine) 91} 92 93func fb([]byte) { 94 panic("unreachable") 95} 96 97func p5() { 98 // Array to slice. 99 var p *[1 << 30]byte = nil 100 fb(p[0:]) // should crash 101} 102 103func p6() { 104 // Array to slice. 105 var p *[1 << 30]byte = nil 106 var _ []byte = p[10 : len(p)-10] // should crash 107} 108 109type T struct { 110 x [256 << 20]byte 111 i int 112} 113 114func f() *T { 115 return nil 116} 117 118var y *T 119var x = &y 120 121func p7() { 122 // Struct field access with large offset. 123 println(f().i) // should crash 124} 125 126func p8() { 127 // Struct field access with large offset. 128 println((*x).i) // should crash 129} 130 131func p9() { 132 // Struct field access with large offset. 133 var t *T 134 println(&t.i) // should crash 135} 136 137func p10() { 138 // Struct field access with large offset. 139 var t *T 140 println(t.i) // should crash 141} 142 143type T1 struct { 144 T 145} 146 147type T2 struct { 148 *T1 149} 150 151func p11() { 152 t := &T2{} 153 p := &t.i 154 println(*p) 155} 156 157// ADDR(DOT(IND(p))) needs a check also 158func p12() { 159 var p *T = nil 160 println(*(&((*p).i))) 161} 162 163// Tests suggested in golang.org/issue/6080. 164 165func p13() { 166 var x *[10]int 167 y := x[:] 168 _ = y 169} 170 171func p14() { 172 println((*[1]int)(nil)[:]) 173} 174 175func p15() { 176 for i := range (*[1]int)(nil)[:] { 177 _ = i 178 } 179} 180 181func p16() { 182 for i, v := range (*[1]int)(nil)[:] { 183 _ = i + v 184 } 185} 186