]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
device: receive: drain decryption queue before exiting RoutineDecryption
authorJason A. Donenfeld <Jason@zx2c4.com>
Thu, 7 Jan 2021 14:56:52 +0000 (15:56 +0100)
committerJason A. Donenfeld <Jason@zx2c4.com>
Thu, 7 Jan 2021 16:08:41 +0000 (17:08 +0100)
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 <Jason@zx2c4.com>
device/device.go
device/receive.go

index 31722245ef1473e81b18c612ba9e68d9d7a4bc24..d37fe6f05a4016d7a212f7f934b3c743ca946309 100644 (file)
@@ -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:
index 4b6f278f378d11ca06f2e37ed6eac91322d51cdc..0bd22bff581f23b02a368a7e32f35707119d2e97 100644 (file)
@@ -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: