summaryrefslogtreecommitdiffhomepage
path: root/conn_linux.go
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-05-20 03:37:33 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-05-20 03:37:42 +0200
commita5b3340e5b0a3623e953c88f9c5c0a31d8987b8d (patch)
treef7baa491a8316dcec289138818719ae1823d68d7 /conn_linux.go
parent7c21a3de0adba015250d657e7605a228d5244009 (diff)
Fix race in netlink peer correlator
Diffstat (limited to 'conn_linux.go')
-rw-r--r--conn_linux.go9
1 files changed, 9 insertions, 0 deletions
diff --git a/conn_linux.go b/conn_linux.go
index 848694d..e5105e3 100644
--- a/conn_linux.go
+++ b/conn_linux.go
@@ -21,6 +21,7 @@ import (
"golang.org/x/sys/unix"
"net"
"strconv"
+ "sync"
"unsafe"
)
@@ -551,6 +552,7 @@ func (bind *NativeBind) routineRouteListener(device *Device) {
endpoint *Endpoint
}
var reqPeer map[uint32]peerEndpointPtr
+ var reqPeerLock sync.Mutex
defer unix.Close(bind.netlinkSock)
@@ -596,10 +598,13 @@ func (bind *NativeBind) routineRouteListener(device *Device) {
}
if attrhdr.Type == unix.RTA_OIF && attrhdr.Len == unix.SizeofRtAttr+4 {
ifidx := *(*uint32)(unsafe.Pointer(&attr[unix.SizeofRtAttr]))
+ reqPeerLock.Lock()
if reqPeer == nil {
+ reqPeerLock.Unlock()
break
}
pePtr, ok := reqPeer[hdr.Seq]
+ reqPeerLock.Unlock()
if !ok {
break
}
@@ -620,7 +625,9 @@ func (bind *NativeBind) routineRouteListener(device *Device) {
}
break
}
+ reqPeerLock.Lock()
reqPeer = make(map[uint32]peerEndpointPtr)
+ reqPeerLock.Unlock()
go func() {
device.peers.mutex.RLock()
i := uint32(1)
@@ -671,10 +678,12 @@ func (bind *NativeBind) routineRouteListener(device *Device) {
uint32(bind.lastMark),
}
nlmsg.hdr.Len = uint32(unsafe.Sizeof(nlmsg))
+ reqPeerLock.Lock()
reqPeer[i] = peerEndpointPtr{
peer: peer,
endpoint: &peer.endpoint,
}
+ reqPeerLock.Unlock()
peer.mutex.RUnlock()
i++
_, err := bind.netlinkCancel.Write((*[unsafe.Sizeof(nlmsg)]byte)(unsafe.Pointer(&nlmsg))[:])