aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Maloy <jon.maloy@ericsson.com>2017-12-21 08:36:34 -0500
committerDavid S. Miller <davem@davemloft.net>2017-12-26 13:06:36 -0500
commit3a33a19bf88cdfc6d982972bc6ffcf7a62c1015e (patch)
tree822156ba441ed4d0231d6a5dd54a283aabf5caf8
parent4853f128c13ed2731625dff2410b7fdbe540fb26 (diff)
tipc: fix memory leak of group member when peer node is lost
When a group member receives a member WITHDRAW event, this might have two reasons: either the peer member is leaving the group, or the link to the member's node has been lost. In the latter case we need to issue a DOWN event to the user right away, and let function tipc_group_filter_msg() perform delete of the member item. However, in this case we miss to change the state of the member item to MBR_LEAVING, so the member item is not deleted, and we have a memory leak. We now separate better between the four sub-cases of a WITHRAW event and make sure that each case is handled correctly. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/tipc/group.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/net/tipc/group.c b/net/tipc/group.c
index e5b03f08f076..8e12ab55346b 100644
--- a/net/tipc/group.c
+++ b/net/tipc/group.c
@@ -850,17 +850,26 @@ void tipc_group_member_evt(struct tipc_group *grp,
850 *usr_wakeup = true; 850 *usr_wakeup = true;
851 m->usr_pending = false; 851 m->usr_pending = false;
852 node_up = tipc_node_is_up(net, node); 852 node_up = tipc_node_is_up(net, node);
853 853 m->event_msg = NULL;
854 /* Hold back event if more messages might be expected */ 854
855 if (m->state != MBR_LEAVING && node_up) { 855 if (node_up) {
856 m->event_msg = skb; 856 /* Hold back event if a LEAVE msg should be expected */
857 tipc_group_decr_active(grp, m); 857 if (m->state != MBR_LEAVING) {
858 m->state = MBR_LEAVING; 858 m->event_msg = skb;
859 } else { 859 tipc_group_decr_active(grp, m);
860 if (node_up) 860 m->state = MBR_LEAVING;
861 } else {
861 msg_set_grp_bc_seqno(hdr, m->bc_syncpt); 862 msg_set_grp_bc_seqno(hdr, m->bc_syncpt);
862 else 863 __skb_queue_tail(inputq, skb);
864 }
865 } else {
866 if (m->state != MBR_LEAVING) {
867 tipc_group_decr_active(grp, m);
868 m->state = MBR_LEAVING;
863 msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); 869 msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt);
870 } else {
871 msg_set_grp_bc_seqno(hdr, m->bc_syncpt);
872 }
864 __skb_queue_tail(inputq, skb); 873 __skb_queue_tail(inputq, skb);
865 } 874 }
866 list_del_init(&m->list); 875 list_del_init(&m->list);