1
0
mirror of https://github.com/golang/go synced 2024-11-23 13:20:09 -07:00
go/misc/cgo
Austin Clements f6bff1d587 runtime: fix undead arguments in cgocall
From the garbage collector's perspective, time can move backwards in
cgocall. However, in the midst of this time warp, the pointer
arguments to cgocall can go from dead back to live. If a stack growth
happens while they're dead and then a GC happens when they become live
again, GC can crash with a bad heap pointer.

Specifically, the sequence that leads to a panic is:

1. cgocall calls entersyscall, which saves the PC and SP of its call
site in cgocall. Call this PC/SP "X". At "X" both pointer arguments
are live.

2. cgocall calls asmcgocall. Call the PC/SP of this call "Y". At "Y"
neither pointer argument is live.

3. asmcgocall calls the C code, which eventually calls back into the
Go code.

4. cgocallbackg remembers the saved PC/SP "X" in some local variables,
calls exitsyscall, and then calls cgocallbackg1.

5. The Go code causes a stack growth. This stack unwind sees PC/SP "Y"
in the cgocall frame. Since the arguments are dead at "Y", they are
not adjusted.

6. The Go code returns to cgocallbackg1, which calls reentersyscall
with the recorded saved PC/SP "X", so "X" gets stashed back into
gp.syscallpc/sp.

7. GC scans the stack. It sees there's a saved syscall PC/SP, so it
starts the traceback at PC/SP "X". At "X" the arguments are considered
live, so it scans them, but since they weren't adjusted, the pointers
are bad, so it panics.

This issue started as of commit ca4089ad, when the compiler stopped
marking arguments as live for the whole function.

Since this is a variable liveness issue, fix it by adding KeepAlive
calls that keep the arguments live across this whole time warp.

The existing issue7978 test has all of the infrastructure for testing
this except that it's currently up to chance whether a stack growth
happens in the callback (it currently only happens on the
linux-amd64-noopt builder, for example). Update this test to force a
stack growth, which causes it to fail reliably without this fix.

Fixes #17785.

Change-Id: If706963819ee7814e6705693247bcb97a6f7adb8
Reviewed-on: https://go-review.googlesource.com/33710
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-11-30 17:09:17 +00:00
..
errors cmd/cgo: run cgo pointer checks for pointer to union 2016-11-15 17:10:52 +00:00
fortran misc/cgo/fortran: fix gfortran compile test 2016-05-04 15:08:16 +00:00
gmp all: make copyright headers consistent with one space after period 2016-05-02 13:43:18 +00:00
life all: make copyright headers consistent with one space after period 2016-05-02 13:43:18 +00:00
nocgo
stdio all: make copyright headers consistent with one space after period 2016-05-02 13:43:18 +00:00
test runtime: fix undead arguments in cgocall 2016-11-30 17:09:17 +00:00
testasan
testcarchive runtime: handle SIGPIPE in c-archive and c-shared programs 2016-11-18 01:19:11 +00:00
testcshared misc/cgo/testcshared: add explicit ./ to shared library argument 2016-11-19 04:31:36 +00:00
testgodefs cmd/cgo: add -srcdir option 2016-10-30 19:14:08 +00:00
testplugin cmd/link: handle R_GOTPCREL separately on darwin 2016-11-16 18:37:03 +00:00
testsanitizers runtime/cgo: use libc for sigaction syscalls when possible 2016-11-16 05:38:38 +00:00
testshared cmd/compile, runtime: make the go.itab.* symbols module-local 2016-10-27 19:13:35 +00:00
testsigfwd misc/cgo/testsigfwd: add missing return statement 2016-08-30 21:44:14 +00:00
testso
testsovar misc/cgo/testsovar: needs the extern keyword to export variables on non-windows platforms 2015-07-21 18:10:57 +00:00
testtls all: make copyright headers consistent with one space after period 2016-05-02 13:43:18 +00:00