go: syscall: (*LazyProc).Call does not keep arguments alive (anymore)
What version of Go are you using (go version
)?
$ go version go version go1.13 windows/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env set GO111MODULE= set GOARCH=amd64 set GOBIN= set GOCACHE=C:\Users\elias\AppData\Local\go-build set GOENV=C:\Users\elias\AppData\Roaming\go\env set GOEXE=.exe set GOFLAGS= set GOHOSTARCH=amd64 set GOHOSTOS=windows set GONOPROXY= set GONOSUMDB= set GOOS=windows set GOPATH=C:\Users\elias\go set GOPRIVATE= set GOPROXY=https://proxy.golang.org,direct set GOROOT=c:\go set GOSUMDB=sum.golang.org set GOTMPDIR= set GOTOOLDIR=c:\go\pkg\tool\windows_amd64 set GCCGO=gccgo set AR=ar set CC=gcc set CXX=g++ set CGO_ENABLED=1 set GOMOD= set CGO_CFLAGS=-g -O2 set CGO_CPPFLAGS= set CGO_CXXFLAGS=-g -O2 set CGO_FFLAGS=-g -O2 set CGO_LDFLAGS=-g -O2 set PKG_CONFIG=pkg-config set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\elias\AppData\Local\Temp\go-build579976134=/tmp/go-build -gno-record-gcc-switches
What did you do?
On my Windows 10, run the program from https://play.golang.org/p/2JzHDalGN7Q.
What did you expect to see?
No errors.
What did you see instead?
$ go run .
panic: finalized message before returning from window proc!
goroutine 1 [running, locked to thread]:
main.windowProc(0xb04c8, 0x31f, 0x1, 0x0, 0x7bfc48)
C:/Users/elias/syscallcrash/crash.go:157 +0x186
syscall.Syscall(0x7ffec53f6020, 0x1, 0xc000044000, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/runtime/syscall_windows.go:184 +0xfa
syscall.(*Proc).Call(0xc0000045c0, 0xc000094028, 0x1, 0x1, 0x8, 0x4becc0, 0x4b7001, 0xc000094028)
c:/go/src/syscall/dll_windows.go:171 +0x136
syscall.(*LazyProc).Call(0xc00006c390, 0xc000094028, 0x1, 0x1, 0x4, 0x4, 0x1, 0x0)
c:/go/src/syscall/dll_windows.go:328 +0x66
main.dispatchMessage(0xc000044000)
C:/Users/elias/syscallcrash/crash.go:207 +0xde
main.CreateWindow(0x1, 0xc000056058)
C:/Users/elias/syscallcrash/crash.go:87 +0x128
main.main()
C:/Users/elias/syscallcrash/crash.go:72 +0x29
exit status 2
Which means that the m *msg
argument to dispatchMessage was finalized before the call to the window procedure callback returned, indicating that the _DispatchMessage.Call
didn’t keep its argument alive.
On my machine, I can comment out the panic and get a native crash instead:
$ go run .
Exception 0xc0000005 0x1 0xc000044010 0x7ffec53f622d
PC=0x7ffec53f622d
syscall.Syscall(0x7ffec53f6020, 0x1, 0xc000044000, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/runtime/syscall_windows.go:184 +0xfa
syscall.(*Proc).Call(0xc0000045c0, 0xc000010038, 0x1, 0x1, 0x8, 0x4becc0, 0x4b7001, 0xc000010038)
c:/go/src/syscall/dll_windows.go:171 +0x136
syscall.(*LazyProc).Call(0xc00006c390, 0xc000010038, 0x1, 0x1, 0x4, 0x4, 0x1, 0x0)
c:/go/src/syscall/dll_windows.go:328 +0x66
main.dispatchMessage(0xc000044000)
C:/Users/elias/syscallcrash/crash.go:207 +0xde
main.CreateWindow(0x1, 0xc000056058)
C:/Users/elias/syscallcrash/crash.go:87 +0x128
main.main()
C:/Users/elias/syscallcrash/crash.go:72 +0x29
goroutine 6 [chan receive]:
main.init.0.func1()
C:/Users/elias/syscallcrash/crash.go:126 +0x74
created by main.init.0
C:/Users/elias/syscallcrash/crash.go:125 +0x3c
rax 0x0
rbx 0x25ed820
rcx 0x151040
rdi 0x45c640
rsi 0xc000044000
rbp 0xc000049cc0
rsp 0x7bfd90
r8 0x7bfc90
r9 0x7ffec089e2a8
r10 0x0
r11 0x7bfd60
r12 0x4cfe20
r13 0x0
r14 0x1
r15 0x0
rip 0x7ffec53f622d
rflags 0x10246
cs 0x33
fs 0x53
gs 0x2b
exit status 2
This issue seems like a variant of https://github.com/golang/go/issues/16035. And sure enough, adding runtime.KeepAlive(m)
to dispatchMessage does fix the native crash above.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 29 (27 by maintainers)
I’m marking this for Go 1.14 because I think some fix should make the release. If nothing else, I’d like the CL 198043 fix for regular LazyProc.Calls to go in.
@mdempsky with your CL 198043 applied, my program no longer crashes and @zx2c4’s program no longer prints “UaF”.