diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-05-06 10:45:43 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-05-06 10:50:20 +0200 |
commit | d6a8e9d4dc8d6b5eb5b2e0341ef6e43aeb9c5c49 (patch) | |
tree | 87fd11374b09d02395f0e91cfb84a704b16d7ad6 /tunnel/src/main | |
parent | bcd8c33005bcb776ba3a94f3f18940844d3ffe67 (diff) |
tunnel: avoid race between shutdown and stats
wgTurnOff can block for a while, in which case, calling getStatistics
will use a stale handle and stale tunnel. Not only that, but wgGetConfig
might return null, in which case string.split throws.
java.lang.NullPointerException: Attempt to invoke virtual method
'java.lang.String[] java.lang.String.split(java.lang.String)' on a null
at com.wireguard.android.backend.GoBackend.getStatistics
Reported-by: tomt@adslweb.co.uk
Link: https://lists.zx2c4.com/pipermail/wireguard/2021-May/006709.html
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'tunnel/src/main')
-rw-r--r-- | tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java index c7381487..8b9213db 100644 --- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java +++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java @@ -68,7 +68,7 @@ public final class GoBackend implements Backend { alwaysOnCallback = cb; } - private static native String wgGetConfig(int handle); + @Nullable private static native String wgGetConfig(int handle); private static native int wgGetSocketV4(int handle); @@ -115,10 +115,11 @@ public final class GoBackend implements Backend { @Override public Statistics getStatistics(final Tunnel tunnel) { final Statistics stats = new Statistics(); - if (tunnel != currentTunnel) { + if (tunnel != currentTunnel || currentTunnelHandle == -1) return stats; - } final String config = wgGetConfig(currentTunnelHandle); + if (config == null) + return stats; Key key = null; long rx = 0; long tx = 0; @@ -294,11 +295,11 @@ public final class GoBackend implements Backend { Log.w(TAG, "Tunnel already down"); return; } - - wgTurnOff(currentTunnelHandle); + int handleToClose = currentTunnelHandle; currentTunnel = null; currentTunnelHandle = -1; currentConfig = null; + wgTurnOff(handleToClose); } tunnel.onStateChange(state); |