mirror of
https://github.com/golang/go
synced 2024-11-18 12:44:49 -07:00
7b1e0bb79c
Change-Id: I5d02279d0593a8368b2f249a6b53650b89aed7b7 Reviewed-on: https://go-review.googlesource.com/c/go/+/482275 Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
76 lines
1.4 KiB
Go
76 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)
|
|
}
|