mirror of
https://github.com/golang/go
synced 2024-11-17 02:24:42 -07:00
8f1e2d4ef7
If we run 'go test ./...' in the misc module, we don't want to see errors for these standalone files. We could instead add +ignore tags to each file individually, but this is exactly what a testdata directory is for. Updates #30228 Change-Id: I7047ad888dd6aff701f5982d58b6a79f6a487c58 Reviewed-on: https://go-review.googlesource.com/c/163417 Run-TryBot: Bryan C. Mills <bcmills@google.com> Reviewed-by: Jay Conrod <jayconrod@google.com>
73 lines
1.4 KiB
Go
73 lines
1.4 KiB
Go
// Copyright 2018 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package main
|
|
|
|
// A C function returning a value on the Go stack could leave the Go
|
|
// stack marked as uninitialized, potentially causing a later error
|
|
// when the stack is used for something else. Issue 26209.
|
|
|
|
/*
|
|
#cgo LDFLAGS: -fsanitize=memory
|
|
#cgo CPPFLAGS: -fsanitize=memory
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct {
|
|
uintptr_t a[20];
|
|
} S;
|
|
|
|
S f() {
|
|
S *p;
|
|
|
|
p = (S *)(malloc(sizeof(S)));
|
|
p->a[0] = 0;
|
|
return *p;
|
|
}
|
|
*/
|
|
import "C"
|
|
|
|
// allocateStack extends the stack so that stack copying doesn't
|
|
// confuse the msan data structures.
|
|
//go:noinline
|
|
func allocateStack(i int) int {
|
|
if i == 0 {
|
|
return i
|
|
}
|
|
return allocateStack(i - 1)
|
|
}
|
|
|
|
// F1 marks a chunk of stack as uninitialized.
|
|
// C.f returns an uninitialized struct on the stack, so msan will mark
|
|
// the stack as uninitialized.
|
|
//go:noinline
|
|
func F1() uintptr {
|
|
s := C.f()
|
|
return uintptr(s.a[0])
|
|
}
|
|
|
|
// F2 allocates a struct on the stack and converts it to an empty interface,
|
|
// which will call msanread and see that the data appears uninitialized.
|
|
//go:noinline
|
|
func F2() interface{} {
|
|
return C.S{}
|
|
}
|
|
|
|
func poisonStack(i int) int {
|
|
if i == 0 {
|
|
return int(F1())
|
|
}
|
|
F1()
|
|
r := poisonStack(i - 1)
|
|
F2()
|
|
return r
|
|
}
|
|
|
|
func main() {
|
|
allocateStack(16384)
|
|
poisonStack(128)
|
|
}
|