diff options
author | Jon Maloy <jon.maloy@ericsson.com> | 2017-12-21 08:36:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-12-26 13:06:36 -0500 |
commit | 3a33a19bf88cdfc6d982972bc6ffcf7a62c1015e (patch) | |
tree | 822156ba441ed4d0231d6a5dd54a283aabf5caf8 | |
parent | 4853f128c13ed2731625dff2410b7fdbe540fb26 (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.c | 27 |
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); |