summaryrefslogtreecommitdiffstats
path: root/device/receive.go
diff options
context:
space:
mode:
authorKristupas Antanavičius <kristupas.antanavicius@nordsec.com>2021-04-12 14:50:58 +0300
committerJason A. Donenfeld <Jason@zx2c4.com>2021-04-12 11:14:53 -0600
commitd2fd0c0cc07029f879f6611d3b52e4c33bd78b0b (patch)
tree755c13d27a0101086e7249afc16932d4ecaa9ac6 /device/receive.go
parentconn: windows: reset ring to starting position after free (diff)
downloadwireguard-go-d2fd0c0cc07029f879f6611d3b52e4c33bd78b0b.tar.xz
wireguard-go-d2fd0c0cc07029f879f6611d3b52e4c33bd78b0b.zip
device: allocate new buffer in receive death spiral
Note: this bug is "hidden" by avoiding "death spiral" code path by 6228659 ("device: handle broader range of errors in RoutineReceiveIncoming"). If the code reached "death spiral" mechanism, there would be multiple double frees happening. This results in a deadlock on iOS, because the pools are fixed size and goroutine might stop until somebody makes space in the pool. This was almost 100% repro on the new ARM Macbooks: - Build with 'ios' tag for Mac. This will enable bounded pools. - Somehow call device.IpcSet at least couple of times (update config) - device.BindUpdate() would be triggered - RoutineReceiveIncoming would enter "death spiral". - RoutineReceiveIncoming would stall on double free (pool is already full) - The stuck routine would deadlock 'device.closeBindLocked()' function on line 'netc.stopping.Wait()' Signed-off-by: Kristupas Antanavičius <kristupas.antanavicius@nordsec.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'device/receive.go')
-rw-r--r--device/receive.go1
1 files changed, 1 insertions, 0 deletions
diff --git a/device/receive.go b/device/receive.go
index fa5c0a6..3aa4458 100644
--- a/device/receive.go
+++ b/device/receive.go
@@ -104,6 +104,7 @@ func (device *Device) RoutineReceiveIncoming(recv conn.ReceiveFunc) {
if deathSpiral < 10 {
deathSpiral++
time.Sleep(time.Second / 3)
+ buffer = device.GetMessageBuffer()
continue
}
return