aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-03-17 22:12:10 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-17 22:12:10 -0400
commite7a9eee53cf10cb32fb28ccaacfa98a6220b7276 (patch)
tree63ae1de352f41570ea39d5fa5dd2c2dff5696dc6 /net/tipc
parent5284143057708af297eea10812a67d18e42e9abe (diff)
parent2b9bb7f338502d9d01543daa9fdf4a7f104bd572 (diff)
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>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/name_table.c4
-rw-r--r--net/tipc/server.c47
-rw-r--r--net/tipc/socket.c83
-rw-r--r--net/tipc/socket.h4
4 files changed, 44 insertions, 94 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 105ba7adf06f..ab0ac62a1287 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -811,8 +811,8 @@ static void tipc_purge_publications(struct net *net, struct name_seq *seq)
811 sseq = seq->sseqs; 811 sseq = seq->sseqs;
812 info = sseq->info; 812 info = sseq->info;
813 list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) { 813 list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) {
814 tipc_nametbl_remove_publ(net, publ->type, publ->lower, 814 tipc_nameseq_remove_publ(net, seq, publ->lower, publ->node,
815 publ->node, publ->ref, publ->key); 815 publ->ref, publ->key);
816 kfree_rcu(publ, rcu); 816 kfree_rcu(publ, rcu);
817 } 817 }
818 hlist_del_init_rcu(&seq->ns_list); 818 hlist_del_init_rcu(&seq->ns_list);
diff --git a/net/tipc/server.c b/net/tipc/server.c
index eadd4ed45905..ab6183cdb121 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -37,11 +37,13 @@
37#include "core.h" 37#include "core.h"
38#include "socket.h" 38#include "socket.h"
39#include <net/sock.h> 39#include <net/sock.h>
40#include <linux/module.h>
40 41
41/* Number of messages to send before rescheduling */ 42/* Number of messages to send before rescheduling */
42#define MAX_SEND_MSG_COUNT 25 43#define MAX_SEND_MSG_COUNT 25
43#define MAX_RECV_MSG_COUNT 25 44#define MAX_RECV_MSG_COUNT 25
44#define CF_CONNECTED 1 45#define CF_CONNECTED 1
46#define CF_SERVER 2
45 47
46#define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data) 48#define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data)
47 49
@@ -88,9 +90,19 @@ static void tipc_clean_outqueues(struct tipc_conn *con);
88static void tipc_conn_kref_release(struct kref *kref) 90static void tipc_conn_kref_release(struct kref *kref)
89{ 91{
90 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); 92 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
93 struct sockaddr_tipc *saddr = con->server->saddr;
94 struct socket *sock = con->sock;
95 struct sock *sk;
91 96
92 if (con->sock) { 97 if (sock) {
93 tipc_sock_release_local(con->sock); 98 sk = sock->sk;
99 if (test_bit(CF_SERVER, &con->flags)) {
100 __module_get(sock->ops->owner);
101 __module_get(sk->sk_prot_creator->owner);
102 }
103 saddr->scope = -TIPC_NODE_SCOPE;
104 kernel_bind(sock, (struct sockaddr *)saddr, sizeof(*saddr));
105 sk_release_kernel(sk);
94 con->sock = NULL; 106 con->sock = NULL;
95 } 107 }
96 108
@@ -281,7 +293,7 @@ static int tipc_accept_from_sock(struct tipc_conn *con)
281 struct tipc_conn *newcon; 293 struct tipc_conn *newcon;
282 int ret; 294 int ret;
283 295
284 ret = tipc_sock_accept_local(sock, &newsock, O_NONBLOCK); 296 ret = kernel_accept(sock, &newsock, O_NONBLOCK);
285 if (ret < 0) 297 if (ret < 0)
286 return ret; 298 return ret;
287 299
@@ -309,9 +321,12 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
309 struct socket *sock = NULL; 321 struct socket *sock = NULL;
310 int ret; 322 int ret;
311 323
312 ret = tipc_sock_create_local(s->net, s->type, &sock); 324 ret = sock_create_kern(AF_TIPC, SOCK_SEQPACKET, 0, &sock);
313 if (ret < 0) 325 if (ret < 0)
314 return NULL; 326 return NULL;
327
328 sk_change_net(sock->sk, s->net);
329
315 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE, 330 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,
316 (char *)&s->imp, sizeof(s->imp)); 331 (char *)&s->imp, sizeof(s->imp));
317 if (ret < 0) 332 if (ret < 0)
@@ -337,11 +352,31 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
337 pr_err("Unknown socket type %d\n", s->type); 352 pr_err("Unknown socket type %d\n", s->type);
338 goto create_err; 353 goto create_err;
339 } 354 }
355
356 /* As server's listening socket owner and creator is the same module,
357 * we have to decrease TIPC module reference count to guarantee that
358 * it remains zero after the server socket is created, otherwise,
359 * executing "rmmod" command is unable to make TIPC module deleted
360 * after TIPC module is inserted successfully.
361 *
362 * However, the reference count is ever increased twice in
363 * sock_create_kern(): one is to increase the reference count of owner
364 * of TIPC socket's proto_ops struct; another is to increment the
365 * reference count of owner of TIPC proto struct. Therefore, we must
366 * decrement the module reference count twice to ensure that it keeps
367 * zero after server's listening socket is created. Of course, we
368 * must bump the module reference count twice as well before the socket
369 * is closed.
370 */
371 module_put(sock->ops->owner);
372 module_put(sock->sk->sk_prot_creator->owner);
373 set_bit(CF_SERVER, &con->flags);
374
340 return sock; 375 return sock;
341 376
342create_err: 377create_err:
343 sock_release(sock); 378 kernel_sock_shutdown(sock, SHUT_RDWR);
344 con->sock = NULL; 379 sk_release_kernel(sock->sk);
345 return NULL; 380 return NULL;
346} 381}
347 382
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 934947f038b6..813847d25a49 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -121,9 +121,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz);
121static const struct proto_ops packet_ops; 121static const struct proto_ops packet_ops;
122static const struct proto_ops stream_ops; 122static const struct proto_ops stream_ops;
123static const struct proto_ops msg_ops; 123static const struct proto_ops msg_ops;
124
125static struct proto tipc_proto; 124static struct proto tipc_proto;
126static struct proto tipc_proto_kern;
127 125
128static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { 126static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
129 [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, 127 [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC },
@@ -341,11 +339,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
341 } 339 }
342 340
343 /* Allocate socket's protocol area */ 341 /* Allocate socket's protocol area */
344 if (!kern) 342 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto);
345 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto);
346 else
347 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern);
348
349 if (sk == NULL) 343 if (sk == NULL)
350 return -ENOMEM; 344 return -ENOMEM;
351 345
@@ -383,75 +377,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
383 return 0; 377 return 0;
384} 378}
385 379
386/**
387 * tipc_sock_create_local - create TIPC socket from inside TIPC module
388 * @type: socket type - SOCK_RDM or SOCK_SEQPACKET
389 *
390 * We cannot use sock_creat_kern here because it bumps module user count.
391 * Since socket owner and creator is the same module we must make sure
392 * that module count remains zero for module local sockets, otherwise
393 * we cannot do rmmod.
394 *
395 * Returns 0 on success, errno otherwise
396 */
397int tipc_sock_create_local(struct net *net, int type, struct socket **res)
398{
399 int rc;
400
401 rc = sock_create_lite(AF_TIPC, type, 0, res);
402 if (rc < 0) {
403 pr_err("Failed to create kernel socket\n");
404 return rc;
405 }
406 tipc_sk_create(net, *res, 0, 1);
407
408 return 0;
409}
410
411/**
412 * tipc_sock_release_local - release socket created by tipc_sock_create_local
413 * @sock: the socket to be released.
414 *
415 * Module reference count is not incremented when such sockets are created,
416 * so we must keep it from being decremented when they are released.
417 */
418void tipc_sock_release_local(struct socket *sock)
419{
420 tipc_release(sock);
421 sock->ops = NULL;
422 sock_release(sock);
423}
424
425/**
426 * tipc_sock_accept_local - accept a connection on a socket created
427 * with tipc_sock_create_local. Use this function to avoid that
428 * module reference count is inadvertently incremented.
429 *
430 * @sock: the accepting socket
431 * @newsock: reference to the new socket to be created
432 * @flags: socket flags
433 */
434
435int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
436 int flags)
437{
438 struct sock *sk = sock->sk;
439 int ret;
440
441 ret = sock_create_lite(sk->sk_family, sk->sk_type,
442 sk->sk_protocol, newsock);
443 if (ret < 0)
444 return ret;
445
446 ret = tipc_accept(sock, *newsock, flags);
447 if (ret < 0) {
448 sock_release(*newsock);
449 return ret;
450 }
451 (*newsock)->ops = sock->ops;
452 return ret;
453}
454
455static void tipc_sk_callback(struct rcu_head *head) 380static void tipc_sk_callback(struct rcu_head *head)
456{ 381{
457 struct tipc_sock *tsk = container_of(head, struct tipc_sock, rcu); 382 struct tipc_sock *tsk = container_of(head, struct tipc_sock, rcu);
@@ -2608,12 +2533,6 @@ static struct proto tipc_proto = {
2608 .sysctl_rmem = sysctl_tipc_rmem 2533 .sysctl_rmem = sysctl_tipc_rmem
2609}; 2534};
2610 2535
2611static struct proto tipc_proto_kern = {
2612 .name = "TIPC",
2613 .obj_size = sizeof(struct tipc_sock),
2614 .sysctl_rmem = sysctl_tipc_rmem
2615};
2616
2617/** 2536/**
2618 * tipc_socket_init - initialize TIPC socket interface 2537 * tipc_socket_init - initialize TIPC socket interface
2619 * 2538 *
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 238f1b7bd9bd..bf6551389522 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -44,10 +44,6 @@
44 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE)) 44 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
45int tipc_socket_init(void); 45int tipc_socket_init(void);
46void tipc_socket_stop(void); 46void tipc_socket_stop(void);
47int tipc_sock_create_local(struct net *net, int type, struct socket **res);
48void tipc_sock_release_local(struct socket *sock);
49int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
50 int flags);
51int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); 47int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq);
52void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, 48void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
53 struct sk_buff_head *inputq); 49 struct sk_buff_head *inputq);