summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2016-07-22 14:27:43 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2016-07-22 14:27:43 +0200
commitdb06e909a5adc28671b79a032b09028397f5a33b (patch)
treeddf02be289d0dd0d9c0d647786c48ddab9cfef57
parentsocket: reset IPv4 socket to NULL after free (diff)
downloadwireguard-monolithic-historical-db06e909a5adc28671b79a032b09028397f5a33b.tar.xz
wireguard-monolithic-historical-db06e909a5adc28671b79a032b09028397f5a33b.zip
socket: fix compat for 4.1 v6 sockets
It turns out 4.1 is even more broken than expected. While both 4.1 and 4.2 need to jigger the sysctl nob temporarily, it turns out that in 4.1 it's looking in the wrong namespace for the nob value. So, we have to account for the different namespace semantics in the different versions. Super ugly. But, all this code goes away once we upstream.
-rw-r--r--src/socket.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/socket.c b/src/socket.c
index 9dd1683..aa17c1b 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -423,6 +423,7 @@ int socket_init(struct wireguard_device *wg)
int ret = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
int old_bindv6only;
+ struct net *nobns;
#endif
mutex_lock(&wg->socket_update_lock);
@@ -453,15 +454,20 @@ int socket_init(struct wireguard_device *wg)
#if IS_ENABLED(CONFIG_IPV6)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
+ nobns = &init_net;
+#else
+ nobns = wg->creating_net;
+#endif
/* Since udp_port_cfg only learned of ipv6_v6only in 4.3, we do this horrible
* hack here and set the sysctl variable temporarily to something that will
* set the right option for us in sock_create. It's super racey! */
- old_bindv6only = wg->creating_net->ipv6.sysctl.bindv6only;
- wg->creating_net->ipv6.sysctl.bindv6only = 1;
+ old_bindv6only = nobns->ipv6.sysctl.bindv6only;
+ nobns->ipv6.sysctl.bindv6only = 1;
#endif
ret = udp_sock_create(wg->creating_net, &port6, &new6);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
- wg->creating_net->ipv6.sysctl.bindv6only = old_bindv6only;
+ nobns->ipv6.sysctl.bindv6only = old_bindv6only;
#endif
if (ret < 0) {
pr_err("Could not create IPv6 socket\n");