diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-12-06 18:31:49 +0100 |
---|---|---|
committer | Bruno Martins <bgcngm@gmail.com> | 2023-11-06 09:28:24 +0000 |
commit | 7d5fcdcf62f01cff58dc84080e265a6da1e91e92 (patch) | |
tree | 146bd088765ae88bf3ff4e1274f8b6be021c09c8 | |
parent | 0762a41e1f484192f5d5b2b78e1b62b1ccb1e871 (diff) |
compat: udp_tunnel: don't take reference to non-init namespace
The comment to sk_change_net is instructive:
Kernel sockets, f.e. rtnl or icmp_socket, are a part of a namespace.
They should not hold a reference to a namespace in order to allow
to stop it.
Sockets after sk_change_net should be released using sk_release_kernel
We weren't following these rules before, and were instead using
__sock_create, which means we kept a reference to the namespace, which
in turn meant that interfaces were not cleaned up on namespace
exit.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Change-Id: I03b2e58e45e3eb37c6324b23ca0d6f3fde2ebec7
-rw-r--r-- | drivers/net/wireguard/compat/udp_tunnel/udp_tunnel.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/net/wireguard/compat/udp_tunnel/udp_tunnel.c b/drivers/net/wireguard/compat/udp_tunnel/udp_tunnel.c index 9b8770ae7b3f..d287b917be84 100644 --- a/drivers/net/wireguard/compat/udp_tunnel/udp_tunnel.c +++ b/drivers/net/wireguard/compat/udp_tunnel/udp_tunnel.c @@ -38,9 +38,10 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg, struct socket *sock = NULL; struct sockaddr_in udp_addr; - err = __sock_create(net, AF_INET, SOCK_DGRAM, 0, &sock, 1); + err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock); if (err < 0) goto error; + sk_change_net(sock->sk, net); udp_addr.sin_family = AF_INET; udp_addr.sin_addr = cfg->local_ip; @@ -72,7 +73,7 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg, error: if (sock) { kernel_sock_shutdown(sock, SHUT_RDWR); - sock_release(sock); + sk_release_kernel(sock->sk); } *sockp = NULL; return err; @@ -229,7 +230,7 @@ void udp_tunnel_sock_release(struct socket *sock) { rcu_assign_sk_user_data(sock->sk, NULL); kernel_sock_shutdown(sock, SHUT_RDWR); - sock_release(sock); + sk_release_kernel(sock->sk); } #if IS_ENABLED(CONFIG_IPV6) @@ -254,9 +255,10 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, int err; struct socket *sock = NULL; - err = __sock_create(net, AF_INET6, SOCK_DGRAM, 0, &sock, 1); + err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock); if (err < 0) goto error; + sk_change_net(sock->sk, net); if (cfg->ipv6_v6only) { int val = 1; @@ -301,7 +303,7 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, error: if (sock) { kernel_sock_shutdown(sock, SHUT_RDWR); - sock_release(sock); + sk_release_kernel(sock->sk); } *sockp = NULL; return err; |