Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reflect: memory corruption when operating on pointer types #32547

Closed
acln0 opened this issue Jun 11, 2019 · 3 comments
Closed

reflect: memory corruption when operating on pointer types #32547

acln0 opened this issue Jun 11, 2019 · 3 comments

Comments

@acln0
Copy link
Contributor

acln0 commented Jun 11, 2019

What version of Go are you using (go version)?

$ go version
go version go1.12 linux/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
GOARCH="amd64"
GOBIN="/home/acln/bin"
GOCACHE="/home/acln/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/acln/src/gopath"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build938821885=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I ran the following program: https://play.golang.org/p/Oawu1xbQTSN

The number of * in that one is 250. Moving forward, this program is named P250. P250 runs fine, both in the playground and on my local machine. For all x >= 0 && x <= 250, the respective program Px appears to work fine.

P251

This is P251: https://play.golang.org/p/mm0AO0I8F4M. It is P250, but with an added *.

In the playground, P251 appears to be an infinite loop: https://play.golang.org/p/-P4HziKyv9W

On my local machine, however, I get the following from P251, which is perhaps more enlightening:

: forge:reflectcorruption ; ./reflectcorruption
panic: runtime error: growslice: cap out of range

goroutine 1 [running]:
fmt.(*buffer).WriteString(...)
	/usr/local/go/src/fmt/print.go:83
fmt.(*fmt).padString(0xc000088040, 0x63202c6f6c6c6568, 0x772074707572726f)
	/usr/local/go/src/fmt/format.go:110 +0xfa
fmt.(*fmt).fmtS(0xc000088040, 0x63202c6f6c6c6568, 0x772074707572726f)
	/usr/local/go/src/fmt/format.go:347 +0x61
fmt.(*pp).fmtString(0xc000088000, 0x63202c6f6c6c6568, 0x772074707572726f, 0xc000000076)
	/usr/local/go/src/fmt/print.go:448 +0x132
fmt.(*pp).printArg(0xc000088000, 0x49da40, 0xc0000101f0, 0x76)
	/usr/local/go/src/fmt/print.go:684 +0x880
fmt.(*pp).doPrintln(0xc000088000, 0xc000041f78, 0x1, 0x1)
	/usr/local/go/src/fmt/print.go:1159 +0xb2
fmt.Fprintln(0x4e00a0, 0xc00000e018, 0xc000082f78, 0x1, 0x1, 0x98, 0x0, 0x0)
	/usr/local/go/src/fmt/print.go:265 +0x58
fmt.Println(...)
	/usr/local/go/src/fmt/print.go:275
main.main()
	/home/acln/src/reflectcorruption/main.go:12 +0x157a

Note the bogus addresses in the fmt.(*pp).fmtString frame:

  • 0x63202c6f6c6c6568 is c ,olleh
  • 0x772074707572726f is w tpurro

P252

P252 is also an infinite loop in the playground, but crashes on my local machine like so:

: forge:reflectcorruption ; ./reflectcorruption
unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x488567]

goroutine 1 [running]:
runtime.throw(0x4c60a8, 0x5)
	/usr/local/go/src/runtime/panic.go:617 +0x72 fp=0xc00008a778 sp=0xc00008a748 pc=0x427ba2
runtime.sigpanic()
	/usr/local/go/src/runtime/signal_unix.go:397 +0x401 fp=0xc00008a7a8 sp=0xc00008a778 pc=0x43a301
main.main()
	/home/acln/src/reflectcorruption/main.go:12 +0x1517 fp=0xc00008af98 sp=0xc00008a7a8 pc=0x488567
runtime.main()
	/usr/local/go/src/runtime/proc.go:200 +0x20c fp=0xc00008afe0 sp=0xc00008af98 pc=0x4294ec
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00008afe8 sp=0xc00008afe0 pc=0x450ad1

P253 and onwards

These seem to be infinite loops wherever I run them.

What did you expect to see?

I expected P251 and onwards to work just as P250 did.

What did you see instead?

P251 and subsequent programs appear to corrupt memory, loop infinitely, or crash in mysterious ways.

@acln0
Copy link
Contributor Author

acln0 commented Jun 11, 2019

I will note that this bug most certainly did not show up in a real program, and is merely the result of the #darkarts channel on the Gophers Slack poking at the reflect package.

@ianlancetaylor
Copy link
Contributor

Interesting test case. This is an instance of #29312. Closing in favor of that issue.

@as
Copy link
Contributor

as commented Jun 11, 2019

@acln0 of note, P500000 crashes the builder with a stack overflow.

@golang golang locked and limited conversation to collaborators Jun 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants