diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-05-20 03:37:33 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-05-20 03:37:42 +0200 |
commit | a5b3340e5b0a3623e953c88f9c5c0a31d8987b8d (patch) | |
tree | f7baa491a8316dcec289138818719ae1823d68d7 /conn_linux.go | |
parent | 7c21a3de0adba015250d657e7605a228d5244009 (diff) |
Fix race in netlink peer correlator
Diffstat (limited to 'conn_linux.go')
-rw-r--r-- | conn_linux.go | 9 |
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))[:]) |