From: Jason A. Donenfeld Date: Thu, 7 Jan 2021 14:56:52 +0000 (+0100) Subject: device: receive: drain decryption queue before exiting RoutineDecryption X-Git-Tag: 0.0.20210212~105 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29b04775856b62213d7bc01937641e2db081d707;p=thirdparty%2Fwireguard-go.git device: receive: drain decryption queue before exiting RoutineDecryption It's possible for RoutineSequentialReceiver to try to lock an elem after RoutineDecryption has exited. Before this meant we didn't then unlock the elem, so the whole program deadlocked. As well, it looks like the flush code (which is now potentially unnecessary?) wasn't properly dropping the buffers for the not-already-dropped case. Signed-off-by: Jason A. Donenfeld --- diff --git a/device/device.go b/device/device.go index 3172224..d37fe6f 100644 --- a/device/device.go +++ b/device/device.go @@ -371,7 +371,10 @@ func (device *Device) FlushPacketQueues() { select { case elem, ok := <-device.queue.decryption: if ok { - elem.Drop() + if !elem.IsDropped() { + elem.Drop() + device.PutMessageBuffer(elem.buffer) + } } case <-device.queue.handshake: default: diff --git a/device/receive.go b/device/receive.go index 4b6f278..0bd22bf 100644 --- a/device/receive.go +++ b/device/receive.go @@ -251,7 +251,20 @@ func (device *Device) RoutineDecryption() { for { select { case <-device.signals.stop: - return + for { + select { + case elem, ok := <-device.queue.decryption: + if ok { + if !elem.IsDropped() { + elem.Drop() + device.PutMessageBuffer(elem.buffer) + } + elem.Unlock() + } + default: + return + } + } case elem, ok := <-device.queue.decryption: