-
Notifications
You must be signed in to change notification settings - Fork 18k
encoding/gob: memory corruption decoding interface #3175
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
Labels
Milestone
Comments
Oops here is correct file Attachments:
|
Probably a runtime bug, but possibly a gob bug. Labels changed: added priority-go1, removed priority-triage. Owner changed to builder@golang.org. Status changed to Accepted. |
Reproduced on OS X after s;@/;/tmp/;. Labels changed: added go1-must. Owner changed to @rsc. |
This is a standalone program (a slight edit of the one in the report) that I believe serializes all the gob calls across the goroutines. It moves all the network calls to init time. So the main part of the program is just doing gob over a Unix socket: the sender does a gob write, then ch <- 0, the receiver does <-ch, then does a gob read. I don't know how it could be less concurrent. And yet it still crashes. I am starting to wonder if this is gob's fault. Sent to Dmitriy to see if automated tools can tell us anything. Attachments:
|
I do not have enough knowledge about gob, but the error seems to be happening here: #0 encoding/gob.(*Decoder).decodeInterface (dec=0xf8400a0000, ityp=..., state=0xf84009df60, p=1066226048304, indir=1) at src/pkg/encoding/gob/decode.go:711 #1 0x000000000047fd4b in encoding/gob._func_005 (&t=void, i=0xf84009df00, state=0xf84009df60, p=0xf840065d30) at src/pkg/encoding/gob/decode.go:892 #2 0x000000f8400ae262 in ?? () #3 0x000000f8400ad300 in ?? () #4 0x000000000046f2d6 in encoding/gob.(*Decoder).decodeSingle (dec=0xf8400a0000, engine=0xf8400ab480, ut=0xf84009d180, basep=1066226048304) at src/pkg/encoding/gob/decode.go:486 #5 0x000000000047401b in encoding/gob.(*Decoder).decodeValue (dec=0xf8400a0000, wireId=8, val=...) at src/pkg/encoding/gob/decode.go:1230 #6 0x00000000004750cb in encoding/gob.(*Decoder).DecodeValue (dec=0xf8400a0000, v=..., noname=void) at src/pkg/encoding/gob/decoder.go:208 #7 0x0000000000474f47 in encoding/gob.(*Decoder).Decode (dec=0xf8400a0000, e="(*interface {})0xf8400ad2e0", noname=void) at src/pkg/encoding/gob/decoder.go:185 #8 0x0000000000424124 in tmp.requestResponse (enc=0xf84009f000, dec=0xf8400a0000, e=void, noname=void) at src/pkg/tmp/tmp_test.go:88 #9 0x0000000000423f90 in tmp.Client (x=3000, addr="/tmp/experiment.socket") at src/pkg/tmp/tmp_test.go:71 The source line is: *(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData() with the comment "This is horribly unsafe". During decoding of the nil error pointer (request response). Perhaps the type name should not be empty string since it is the error. Or perhaps the value is just written into wrong location. |
Forgot to mention, the source line overwrites beginning on the next (or previous) memory block, perhaps there is space for 1 word, but it overwrites 2. The instruction is: 0x0000000000470679 <+305>: lea 0xe0(%rsp),%rsi 0x0000000000470681 <+313>: lea (%rsp),%rdi 0x0000000000470685 <+317>: movsq %ds:(%rsi),%es:(%rdi) 0x0000000000470687 <+319>: movsq %ds:(%rsi),%es:(%rdi) 0x0000000000470689 <+321>: movsq %ds:(%rsi),%es:(%rdi) 0x000000000047068b <+323>: callq 0x4ade11 <reflect.Value.InterfaceData> 0x0000000000470690 <+328>: lea 0x18(%rsp),%rsi 0x0000000000470695 <+333>: lea 0x148(%rsp),%rdi 0x000000000047069d <+341>: movsq %ds:(%rsi),%es:(%rdi) 0x000000000047069f <+343>: movsq %ds:(%rsi),%es:(%rdi) 0x00000000004706a1 <+345>: mov 0x190(%rsp),%rax 0x00000000004706a9 <+353>: mov %rax,%rdi 0x00000000004706ac <+356>: lea 0x148(%rsp),%rsi 0x00000000004706b4 <+364>: movsq %ds:(%rsi),%es:(%rdi) => 0x00000000004706b6 <+366>: movsq %ds:(%rsi),%es:(%rdi) 0x00000000004706b8 <+368>: add $0x168,%rsp 0x00000000004706bf <+375>: retq Btw, these instructions doubled 2 or 3 times look a bit strange... |
> Btw, these instructions doubled 2 or 3 times look a bit strange... Ah, OK, the instructions modify rsi/rdi. So it's the store to the second word, perhaps it's missing indirection, the code below does: p = allocate(ityp, p, 1) before writing to the 'p'. But here we write directly to 'p'. |
The "nil interface value" case is forgetting to handle the case indir > 0. Try copying the lines // Allocate the destination interface value. if indir > 0 { p = allocate(ityp, p, 1) // All but the last level has been allocated by dec.Indirect } to just after the "horribly unsafe and special" comment. |
It fixes the issue http://golang.org/cl/5758069 |
Owner changed to @dvyukov. |
This issue was closed by revision c8b1f85. Status changed to Fixed. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
by werner.hattingh:
Attachments:
The text was updated successfully, but these errors were encountered: