Skip to content

Commit 8e40dd6

Browse files
committed
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>
1 parent ea6b8e7 commit 8e40dd6

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

src/compat/udp_tunnel/udp_tunnel.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
3838
struct socket *sock = NULL;
3939
struct sockaddr_in udp_addr;
4040

41-
err = __sock_create(net, AF_INET, SOCK_DGRAM, 0, &sock, 1);
41+
err = sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock);
4242
if (err < 0)
4343
goto error;
44+
sk_change_net(sock->sk, net);
4445

4546
udp_addr.sin_family = AF_INET;
4647
udp_addr.sin_addr = cfg->local_ip;
@@ -72,7 +73,7 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg,
7273
error:
7374
if (sock) {
7475
kernel_sock_shutdown(sock, SHUT_RDWR);
75-
sock_release(sock);
76+
sk_release_kernel(sock->sk);
7677
}
7778
*sockp = NULL;
7879
return err;
@@ -229,7 +230,7 @@ void udp_tunnel_sock_release(struct socket *sock)
229230
{
230231
rcu_assign_sk_user_data(sock->sk, NULL);
231232
kernel_sock_shutdown(sock, SHUT_RDWR);
232-
sock_release(sock);
233+
sk_release_kernel(sock->sk);
233234
}
234235

235236
#if IS_ENABLED(CONFIG_IPV6)
@@ -254,9 +255,10 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
254255
int err;
255256
struct socket *sock = NULL;
256257

257-
err = __sock_create(net, AF_INET6, SOCK_DGRAM, 0, &sock, 1);
258+
err = sock_create_kern(AF_INET6, SOCK_DGRAM, 0, &sock);
258259
if (err < 0)
259260
goto error;
261+
sk_change_net(sock->sk, net);
260262

261263
if (cfg->ipv6_v6only) {
262264
int val = 1;
@@ -301,7 +303,7 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg,
301303
error:
302304
if (sock) {
303305
kernel_sock_shutdown(sock, SHUT_RDWR);
304-
sock_release(sock);
306+
sk_release_kernel(sock->sk);
305307
}
306308
*sockp = NULL;
307309
return err;

0 commit comments

Comments
 (0)