Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'tipc_netns_leak'

Ying Xue says:

====================
tipc: fix netns refcnt leak

The series aims to eliminate the issue of netns refcount leak. But
during fixing it, another two additional problems are found. So all
of known issues associated with the netns refcnt leak are resolved
at the same time in the patchset.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+44 -94
+2 -2
net/tipc/name_table.c
··· 811 811 sseq = seq->sseqs; 812 812 info = sseq->info; 813 813 list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) { 814 - tipc_nametbl_remove_publ(net, publ->type, publ->lower, 815 - publ->node, publ->ref, publ->key); 814 + tipc_nameseq_remove_publ(net, seq, publ->lower, publ->node, 815 + publ->ref, publ->key); 816 816 kfree_rcu(publ, rcu); 817 817 } 818 818 hlist_del_init_rcu(&seq->ns_list);
+41 -6
net/tipc/server.c
··· 37 37 #include "core.h" 38 38 #include "socket.h" 39 39 #include <net/sock.h> 40 + #include <linux/module.h> 40 41 41 42 /* Number of messages to send before rescheduling */ 42 43 #define MAX_SEND_MSG_COUNT 25 43 44 #define MAX_RECV_MSG_COUNT 25 44 45 #define CF_CONNECTED 1 46 + #define CF_SERVER 2 45 47 46 48 #define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data) 47 49 ··· 90 88 static void tipc_conn_kref_release(struct kref *kref) 91 89 { 92 90 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); 91 + struct sockaddr_tipc *saddr = con->server->saddr; 92 + struct socket *sock = con->sock; 93 + struct sock *sk; 93 94 94 - if (con->sock) { 95 - tipc_sock_release_local(con->sock); 95 + if (sock) { 96 + sk = sock->sk; 97 + if (test_bit(CF_SERVER, &con->flags)) { 98 + __module_get(sock->ops->owner); 99 + __module_get(sk->sk_prot_creator->owner); 100 + } 101 + saddr->scope = -TIPC_NODE_SCOPE; 102 + kernel_bind(sock, (struct sockaddr *)saddr, sizeof(*saddr)); 103 + sk_release_kernel(sk); 96 104 con->sock = NULL; 97 105 } 98 106 ··· 293 281 struct tipc_conn *newcon; 294 282 int ret; 295 283 296 - ret = tipc_sock_accept_local(sock, &newsock, O_NONBLOCK); 284 + ret = kernel_accept(sock, &newsock, O_NONBLOCK); 297 285 if (ret < 0) 298 286 return ret; 299 287 ··· 321 309 struct socket *sock = NULL; 322 310 int ret; 323 311 324 - ret = tipc_sock_create_local(s->net, s->type, &sock); 312 + ret = sock_create_kern(AF_TIPC, SOCK_SEQPACKET, 0, &sock); 325 313 if (ret < 0) 326 314 return NULL; 315 + 316 + sk_change_net(sock->sk, s->net); 317 + 327 318 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE, 328 319 (char *)&s->imp, sizeof(s->imp)); 329 320 if (ret < 0) ··· 352 337 pr_err("Unknown socket type %d\n", s->type); 353 338 goto create_err; 354 339 } 340 + 341 + /* As server's listening socket owner and creator is the same module, 342 + * we have to decrease TIPC module reference count to guarantee that 343 + * it remains zero after the server socket is created, otherwise, 344 + * executing "rmmod" command is unable to make TIPC module deleted 345 + * after TIPC module is inserted successfully. 346 + * 347 + * However, the reference count is ever increased twice in 348 + * sock_create_kern(): one is to increase the reference count of owner 349 + * of TIPC socket's proto_ops struct; another is to increment the 350 + * reference count of owner of TIPC proto struct. Therefore, we must 351 + * decrement the module reference count twice to ensure that it keeps 352 + * zero after server's listening socket is created. Of course, we 353 + * must bump the module reference count twice as well before the socket 354 + * is closed. 355 + */ 356 + module_put(sock->ops->owner); 357 + module_put(sock->sk->sk_prot_creator->owner); 358 + set_bit(CF_SERVER, &con->flags); 359 + 355 360 return sock; 356 361 357 362 create_err: 358 - sock_release(sock); 359 - con->sock = NULL; 363 + kernel_sock_shutdown(sock, SHUT_RDWR); 364 + sk_release_kernel(sock->sk); 360 365 return NULL; 361 366 } 362 367
+1 -82
net/tipc/socket.c
··· 121 121 static const struct proto_ops packet_ops; 122 122 static const struct proto_ops stream_ops; 123 123 static const struct proto_ops msg_ops; 124 - 125 124 static struct proto tipc_proto; 126 - static struct proto tipc_proto_kern; 127 125 128 126 static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { 129 127 [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, ··· 339 341 } 340 342 341 343 /* Allocate socket's protocol area */ 342 - if (!kern) 343 - sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); 344 - else 345 - sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern); 346 - 344 + sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); 347 345 if (sk == NULL) 348 346 return -ENOMEM; 349 347 ··· 375 381 tsk_set_unreliable(tsk, true); 376 382 } 377 383 return 0; 378 - } 379 - 380 - /** 381 - * tipc_sock_create_local - create TIPC socket from inside TIPC module 382 - * @type: socket type - SOCK_RDM or SOCK_SEQPACKET 383 - * 384 - * We cannot use sock_creat_kern here because it bumps module user count. 385 - * Since socket owner and creator is the same module we must make sure 386 - * that module count remains zero for module local sockets, otherwise 387 - * we cannot do rmmod. 388 - * 389 - * Returns 0 on success, errno otherwise 390 - */ 391 - int tipc_sock_create_local(struct net *net, int type, struct socket **res) 392 - { 393 - int rc; 394 - 395 - rc = sock_create_lite(AF_TIPC, type, 0, res); 396 - if (rc < 0) { 397 - pr_err("Failed to create kernel socket\n"); 398 - return rc; 399 - } 400 - tipc_sk_create(net, *res, 0, 1); 401 - 402 - return 0; 403 - } 404 - 405 - /** 406 - * tipc_sock_release_local - release socket created by tipc_sock_create_local 407 - * @sock: the socket to be released. 408 - * 409 - * Module reference count is not incremented when such sockets are created, 410 - * so we must keep it from being decremented when they are released. 411 - */ 412 - void tipc_sock_release_local(struct socket *sock) 413 - { 414 - tipc_release(sock); 415 - sock->ops = NULL; 416 - sock_release(sock); 417 - } 418 - 419 - /** 420 - * tipc_sock_accept_local - accept a connection on a socket created 421 - * with tipc_sock_create_local. Use this function to avoid that 422 - * module reference count is inadvertently incremented. 423 - * 424 - * @sock: the accepting socket 425 - * @newsock: reference to the new socket to be created 426 - * @flags: socket flags 427 - */ 428 - 429 - int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, 430 - int flags) 431 - { 432 - struct sock *sk = sock->sk; 433 - int ret; 434 - 435 - ret = sock_create_lite(sk->sk_family, sk->sk_type, 436 - sk->sk_protocol, newsock); 437 - if (ret < 0) 438 - return ret; 439 - 440 - ret = tipc_accept(sock, *newsock, flags); 441 - if (ret < 0) { 442 - sock_release(*newsock); 443 - return ret; 444 - } 445 - (*newsock)->ops = sock->ops; 446 - return ret; 447 384 } 448 385 449 386 static void tipc_sk_callback(struct rcu_head *head) ··· 2529 2604 static struct proto tipc_proto = { 2530 2605 .name = "TIPC", 2531 2606 .owner = THIS_MODULE, 2532 - .obj_size = sizeof(struct tipc_sock), 2533 - .sysctl_rmem = sysctl_tipc_rmem 2534 - }; 2535 - 2536 - static struct proto tipc_proto_kern = { 2537 - .name = "TIPC", 2538 2607 .obj_size = sizeof(struct tipc_sock), 2539 2608 .sysctl_rmem = sysctl_tipc_rmem 2540 2609 };
-4
net/tipc/socket.h
··· 44 44 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE)) 45 45 int tipc_socket_init(void); 46 46 void tipc_socket_stop(void); 47 - int tipc_sock_create_local(struct net *net, int type, struct socket **res); 48 - void tipc_sock_release_local(struct socket *sock); 49 - int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, 50 - int flags); 51 47 int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); 52 48 void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, 53 49 struct sk_buff_head *inputq);