Skip to contentSkip to conversation

Patch "tipc: fix nametbl deadlock at tipc_nametbl_unsubscribe" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message Dec 21, 2017

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

tipc: fix nametbl deadlock at tipc_nametbl_unsubscribe

to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
tipc-fix-nametbl-deadlock-at-tipc_nametbl_unsubscribe.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Thu Dec 21 09:02:40 CET 2017

From: Ying Xue <[email protected]>
Date: Tue, 21 Mar 2017 10:47:49 +0100
Subject: tipc: fix nametbl deadlock at tipc_nametbl_unsubscribe

From: Ying Xue <[email protected]>

[ Upstream commit 557d054c01da0337ca81de9e9d9206d57245b57e ]

Until now, tipc_nametbl_unsubscribe() is called at subscriptions reference count cleanup. Usually the subscriptions cleanup is called at subscription timeout or at subscription cancel or at subscriber delete.

We have ignored the possibility of this being called from other locations, which causes deadlock as we try to grab the tn->nametbl_lock while holding it already.

CPU1: CPU2:
---------- ----------------
tipc_nametbl_publish spin_lock_bh(&tn->nametbl_lock) tipc_nametbl_insert_publ tipc_nameseq_insert_publ tipc_subscrp_report_overlap
tipc_subscrp_get
tipc_subscrp_send_event
tipc_close_conn tipc_subscrb_release_cb tipc_subscrb_delete tipc_subscrp_put
tipc_subscrp_put
tipc_subscrp_kref_release tipc_nametbl_unsubscribe spin_lock_bh(&tn->nametbl_lock)
<<grab nametbl_lock again>>

CPU1: CPU2:
---------- ----------------
tipc_nametbl_stop spin_lock_bh(&tn->nametbl_lock) tipc_purge_publications tipc_nameseq_remove_publ tipc_subscrp_report_overlap
tipc_subscrp_get
tipc_subscrp_send_event
tipc_close_conn tipc_subscrb_release_cb tipc_subscrb_delete tipc_subscrp_put
tipc_subscrp_put
tipc_subscrp_kref_release tipc_nametbl_unsubscribe spin_lock_bh(&tn->nametbl_lock)
<<grab nametbl_lock again>>

In this commit, we advance the calling of tipc_nametbl_unsubscribe() from the refcount cleanup to the intended callers.

Fixes d094c4d5f5c7 ("tipc: add subscription refcount to avoid invalid delete")
---
 net/tipc/subscr.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
net/tipc/subscr.c +6 -1
@@ -141,6 +141,11 @@ void tipc_subscrp_report_overlap(struct
 static void tipc_subscrp_timeout(unsigned long data)
 {
 	struct tipc_subscription *sub = (struct tipc_subscription *)data;
+	struct tipc_subscriber *subscriber = sub->subscriber;
+
+	spin_lock_bh(&subscriber->lock);
+	tipc_nametbl_unsubscribe(sub);
+	spin_unlock_bh(&subscriber->lock);
 
 	/* Notify subscriber of timeout */
 	tipc_subscrp_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
@@ -173,7 +178,6 @@ static void tipc_subscrp_kref_release(st
 	struct tipc_subscriber *subscriber = sub->subscriber;
 
 	spin_lock_bh(&subscriber->lock);
-	tipc_nametbl_unsubscribe(sub);
 	list_del(&sub->subscrp_list);
 	atomic_dec(&tn->subscription_count);
 	spin_unlock_bh(&subscriber->lock);
@@ -205,6 +209,7 @@ static void tipc_subscrb_subscrp_delete(
 		if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr)))
 			continue;
 
+		tipc_nametbl_unsubscribe(sub);
 		tipc_subscrp_get(sub);
 		spin_unlock_bh(&subscriber->lock);
 		tipc_subscrp_delete(sub);

Patches currently in stable-queue which might be from [email protected] are

queue-4.9/tipc-fix-nametbl-deadlock-at-tipc_nametbl_unsubscribe.patch