1
0
mirror of https://github.com/golang/go synced 2024-11-22 07:44:43 -07:00

net: fix memory corruption in windows *netFD.ReadFrom

We must keep memory used by syscall.WSARecvFrom away from
garbage collector until after overlapped call is completed.

Fixes #2094.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/4817050
This commit is contained in:
Alex Brainman 2011-07-26 11:55:52 +10:00
parent 83305fecfe
commit 003d5411ae

View File

@ -272,7 +272,7 @@ func (fd *netFD) incref() {
func (fd *netFD) decref() { func (fd *netFD) decref() {
fd.sysmu.Lock() fd.sysmu.Lock()
fd.sysref-- fd.sysref--
if fd.closing && fd.sysref == 0 && fd.sysfd >= 0 { if fd.closing && fd.sysref == 0 && fd.sysfd != syscall.InvalidHandle {
// In case the user has set linger, switch to blocking mode so // In case the user has set linger, switch to blocking mode so
// the close blocks. As long as this doesn't happen often, we // the close blocks. As long as this doesn't happen often, we
// can handle the extra OS processes. Otherwise we'll need to // can handle the extra OS processes. Otherwise we'll need to
@ -338,12 +338,12 @@ func (fd *netFD) Read(buf []byte) (n int, err os.Error) {
type readFromOp struct { type readFromOp struct {
bufOp bufOp
rsa syscall.RawSockaddrAny rsa syscall.RawSockaddrAny
rsan int32
} }
func (o *readFromOp) Submit() (errno int) { func (o *readFromOp) Submit() (errno int) {
var d, f uint32 var d, f uint32
l := int32(unsafe.Sizeof(o.rsa)) return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &d, &f, &o.rsa, &o.rsan, &o.o, nil)
return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &d, &f, &o.rsa, &l, &o.o, nil)
} }
func (o *readFromOp) Name() string { func (o *readFromOp) Name() string {
@ -366,7 +366,11 @@ func (fd *netFD) ReadFrom(buf []byte) (n int, sa syscall.Sockaddr, err os.Error)
} }
var o readFromOp var o readFromOp
o.Init(fd, buf) o.Init(fd, buf)
o.rsan = int32(unsafe.Sizeof(o.rsa))
n, err = iosrv.ExecIO(&o, fd.rdeadline_delta) n, err = iosrv.ExecIO(&o, fd.rdeadline_delta)
if err != nil {
return 0, nil, err
}
sa, _ = o.rsa.Sockaddr() sa, _ = o.rsa.Sockaddr()
return return
} }