github.com/kidsbmilk/gofronted_all@v0.0.0-20220701224323-6479d5976c5d/libgo/misc/cgo/testsanitizers/testdata/msan6.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 // A C function returning a value on the Go stack could leave the Go 8 // stack marked as uninitialized, potentially causing a later error 9 // when the stack is used for something else. Issue 26209. 10 11 /* 12 #cgo LDFLAGS: -fsanitize=memory 13 #cgo CPPFLAGS: -fsanitize=memory 14 15 #include <stdint.h> 16 #include <stdlib.h> 17 #include <string.h> 18 19 typedef struct { 20 uintptr_t a[20]; 21 } S; 22 23 S f() { 24 S *p; 25 26 p = (S *)(malloc(sizeof(S))); 27 p->a[0] = 0; 28 return *p; 29 } 30 */ 31 import "C" 32 33 // allocateStack extends the stack so that stack copying doesn't 34 // confuse the msan data structures. 35 //go:noinline 36 func allocateStack(i int) int { 37 if i == 0 { 38 return i 39 } 40 return allocateStack(i - 1) 41 } 42 43 // F1 marks a chunk of stack as uninitialized. 44 // C.f returns an uninitialized struct on the stack, so msan will mark 45 // the stack as uninitialized. 46 //go:noinline 47 func F1() uintptr { 48 s := C.f() 49 return uintptr(s.a[0]) 50 } 51 52 // F2 allocates a struct on the stack and converts it to an empty interface, 53 // which will call msanread and see that the data appears uninitialized. 54 //go:noinline 55 func F2() interface{} { 56 return C.S{} 57 } 58 59 func poisonStack(i int) int { 60 if i == 0 { 61 return int(F1()) 62 } 63 F1() 64 r := poisonStack(i - 1) 65 F2() 66 return r 67 } 68 69 func main() { 70 allocateStack(16384) 71 poisonStack(128) 72 }