diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-05-02 01:30:23 -0600 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-05-02 01:56:48 -0600 |
commit | 28c4d043048e8bb7167e96df6558a6366306fc17 (patch) | |
tree | c98e39cd6ed75e23f54e6d1b72b6f5c70fa9ab8a /device/noise-protocol.go | |
parent | fdba6c183aa8d4c19680f436517624038a6f3be5 (diff) | |
download | wireguard-go-28c4d043048e8bb7167e96df6558a6366306fc17.tar.gz wireguard-go-28c4d043048e8bb7167e96df6558a6366306fc17.zip |
device: use atomic access for unlocked keypair.next
Go's GC semantics might not always guarantee the safety of this, and the
race detector gets upset too, so instead we wrap this all in atomic
accessors.
Reported-by: David Anderson <danderson@tailscale.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'device/noise-protocol.go')
-rw-r--r-- | device/noise-protocol.go | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/device/noise-protocol.go b/device/noise-protocol.go index a848c47..e6f676c 100644 --- a/device/noise-protocol.go +++ b/device/noise-protocol.go @@ -14,6 +14,7 @@ import ( "golang.org/x/crypto/blake2s" "golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/poly1305" + "golang.zx2c4.com/wireguard/tai64n" ) @@ -583,12 +584,12 @@ func (peer *Peer) BeginSymmetricSession() error { defer keypairs.Unlock() previous := keypairs.previous - next := keypairs.next + next := keypairs.loadNext() current := keypairs.current if isInitiator { if next != nil { - keypairs.next = nil + keypairs.storeNext(nil) keypairs.previous = next device.DeleteKeypair(current) } else { @@ -597,7 +598,7 @@ func (peer *Peer) BeginSymmetricSession() error { device.DeleteKeypair(previous) keypairs.current = keypair } else { - keypairs.next = keypair + keypairs.storeNext(keypair) device.DeleteKeypair(next) keypairs.previous = nil device.DeleteKeypair(previous) @@ -608,18 +609,19 @@ func (peer *Peer) BeginSymmetricSession() error { func (peer *Peer) ReceivedWithKeypair(receivedKeypair *Keypair) bool { keypairs := &peer.keypairs - if keypairs.next != receivedKeypair { + + if keypairs.loadNext() != receivedKeypair { return false } keypairs.Lock() defer keypairs.Unlock() - if keypairs.next != receivedKeypair { + if keypairs.loadNext() != receivedKeypair { return false } old := keypairs.previous keypairs.previous = keypairs.current peer.device.DeleteKeypair(old) - keypairs.current = keypairs.next - keypairs.next = nil + keypairs.current = keypairs.loadNext() + keypairs.storeNext(nil) return true } |