device: SendmsgN mutates the input sockaddr
So we take a new granular lock to prevent concurrent writes from racing. WARNING: DATA RACE Write at 0x00c0011f2740 by goroutine 27: golang.org/x/sys/unix.(*SockaddrInet4).sockaddr() /go/pkg/mod/golang.org/x/sys@v0.0.0-20191105231009-c1f44814a5cd/unix/syscall_linux.go:384 +0x114 golang.org/x/sys/unix.SendmsgN() /go/pkg/mod/golang.org/x/sys@v0.0.0-20191105231009-c1f44814a5cd/unix/syscall_linux.go:1304 +0x288 golang.zx2c4.com/wireguard/device.send4() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/conn_linux.go:485 +0x11f golang.zx2c4.com/wireguard/device.(*nativeBind).Send() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/conn_linux.go:268 +0x1d6 golang.zx2c4.com/wireguard/device.(*Peer).SendBuffer() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/peer.go:151 +0x285 golang.zx2c4.com/wireguard/device.(*Peer).SendHandshakeInitiation() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/send.go:163 +0x692 golang.zx2c4.com/wireguard/device.(*Device).RoutineReadFromTUN() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/send.go:318 +0x4b8 Previous write at 0x00c0011f2740 by goroutine 386: golang.org/x/sys/unix.(*SockaddrInet4).sockaddr() /go/pkg/mod/golang.org/x/sys@v0.0.0-20191105231009-c1f44814a5cd/unix/syscall_linux.go:384 +0x114 golang.org/x/sys/unix.SendmsgN() /go/pkg/mod/golang.org/x/sys@v0.0.0-20191105231009-c1f44814a5cd/unix/syscall_linux.go:1304 +0x288 golang.zx2c4.com/wireguard/device.send4() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/conn_linux.go:485 +0x11f golang.zx2c4.com/wireguard/device.(*nativeBind).Send() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/conn_linux.go:268 +0x1d6 golang.zx2c4.com/wireguard/device.(*Peer).SendBuffer() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/peer.go:151 +0x285 golang.zx2c4.com/wireguard/device.(*Peer).SendHandshakeInitiation() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/send.go:163 +0x692 golang.zx2c4.com/wireguard/device.expiredRetransmitHandshake() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/timers.go:110 +0x40c golang.zx2c4.com/wireguard/device.(*Peer).NewTimer.func1() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/timers.go:42 +0xd8 Goroutine 27 (running) created at: golang.zx2c4.com/wireguard/device.NewDevice() /go/pkg/mod/golang.zx2c4.com/wireguard@v0.0.20191012/device/device.go:322 +0x5e8 main.main() /go/src/x/main.go:102 +0x58e Goroutine 386 (finished) created at: time.goFunc() /usr/local/go/src/time/sleep.go:168 +0x51 Reported-by: Ben Burkert <ben@benburkert.com>
This commit is contained in:
parent
2b242f9393
commit
ddfad453cf
|
@ -43,6 +43,7 @@ type IPv6Source struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type NativeEndpoint struct {
|
type NativeEndpoint struct {
|
||||||
|
sync.Mutex
|
||||||
dst [unsafe.Sizeof(unix.SockaddrInet6{})]byte
|
dst [unsafe.Sizeof(unix.SockaddrInet6{})]byte
|
||||||
src [unsafe.Sizeof(IPv6Source{})]byte
|
src [unsafe.Sizeof(IPv6Source{})]byte
|
||||||
isV6 bool
|
isV6 bool
|
||||||
|
@ -482,7 +483,9 @@ func send4(sock int, end *NativeEndpoint, buff []byte) error {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end.Lock()
|
||||||
_, err := unix.SendmsgN(sock, buff, (*[unsafe.Sizeof(cmsg)]byte)(unsafe.Pointer(&cmsg))[:], end.dst4(), 0)
|
_, err := unix.SendmsgN(sock, buff, (*[unsafe.Sizeof(cmsg)]byte)(unsafe.Pointer(&cmsg))[:], end.dst4(), 0)
|
||||||
|
end.Unlock()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -493,7 +496,9 @@ func send4(sock int, end *NativeEndpoint, buff []byte) error {
|
||||||
if err == unix.EINVAL {
|
if err == unix.EINVAL {
|
||||||
end.ClearSrc()
|
end.ClearSrc()
|
||||||
cmsg.pktinfo = unix.Inet4Pktinfo{}
|
cmsg.pktinfo = unix.Inet4Pktinfo{}
|
||||||
|
end.Lock()
|
||||||
_, err = unix.SendmsgN(sock, buff, (*[unsafe.Sizeof(cmsg)]byte)(unsafe.Pointer(&cmsg))[:], end.dst4(), 0)
|
_, err = unix.SendmsgN(sock, buff, (*[unsafe.Sizeof(cmsg)]byte)(unsafe.Pointer(&cmsg))[:], end.dst4(), 0)
|
||||||
|
end.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -522,7 +527,9 @@ func send6(sock int, end *NativeEndpoint, buff []byte) error {
|
||||||
cmsg.pktinfo.Ifindex = 0
|
cmsg.pktinfo.Ifindex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end.Lock()
|
||||||
_, err := unix.SendmsgN(sock, buff, (*[unsafe.Sizeof(cmsg)]byte)(unsafe.Pointer(&cmsg))[:], end.dst6(), 0)
|
_, err := unix.SendmsgN(sock, buff, (*[unsafe.Sizeof(cmsg)]byte)(unsafe.Pointer(&cmsg))[:], end.dst6(), 0)
|
||||||
|
end.Unlock()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -533,7 +540,9 @@ func send6(sock int, end *NativeEndpoint, buff []byte) error {
|
||||||
if err == unix.EINVAL {
|
if err == unix.EINVAL {
|
||||||
end.ClearSrc()
|
end.ClearSrc()
|
||||||
cmsg.pktinfo = unix.Inet6Pktinfo{}
|
cmsg.pktinfo = unix.Inet6Pktinfo{}
|
||||||
|
end.Lock()
|
||||||
_, err = unix.SendmsgN(sock, buff, (*[unsafe.Sizeof(cmsg)]byte)(unsafe.Pointer(&cmsg))[:], end.dst6(), 0)
|
_, err = unix.SendmsgN(sock, buff, (*[unsafe.Sizeof(cmsg)]byte)(unsafe.Pointer(&cmsg))[:], end.dst6(), 0)
|
||||||
|
end.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in a new issue