[commits] [batman-adv] maint, master: batman-adv: mcast: fix multicast tt/tvlv worker locking (b736cf81)

postmaster at open-mesh.org postmaster at open-mesh.org
Sun May 5 09:19:04 CEST 2019


Repository : ssh://git@open-mesh.org/batman-adv

On branches: maint,master

>---------------------------------------------------------------

commit b736cf8119cfbc9d95fef90c8832fdec6e8f29c7
Author: Linus Lüssing <linus.luessing at c0d3.blue>
Date:   Wed Apr 24 03:19:14 2019 +0200

    batman-adv: mcast: fix multicast tt/tvlv worker locking
    
    Syzbot has reported some issues with the locking assumptions made for
    the multicast tt/tvlv worker: It was able to trigger the WARN_ON() in
    batadv_mcast_mla_tt_retract() and batadv_mcast_mla_tt_add().
    While hard/not reproduceable for us so far it seems that the
    delayed_work_pending() we use might not be quite safe from reordering.
    
    Therefore this patch adds an explicit, new spinlock to protect the
    update of the mla_list and flags in bat_priv and then removes the
    WARN_ON(delayed_work_pending()).
    
    Reported-by: syzbot+83f2d54ec6b7e417e13f at syzkaller.appspotmail.com
    Reported-by: syzbot+050927a651272b145a5d at syzkaller.appspotmail.com
    Reported-by: syzbot+979ffc89b87309b1b94b at syzkaller.appspotmail.com
    Reported-by: syzbot+f9f3f388440283da2965 at syzkaller.appspotmail.com
    Fixes: 40b384052672 ("batman-adv: Use own timer for multicast TT and TVLV updates")
    Signed-off-by: Linus Lüssing <linus.luessing at c0d3.blue>
    Signed-off-by: Sven Eckelmann <sven at narfation.org>


>---------------------------------------------------------------

b736cf8119cfbc9d95fef90c8832fdec6e8f29c7
 net/batman-adv/main.c      |  1 +
 net/batman-adv/multicast.c | 11 +++--------
 net/batman-adv/types.h     |  5 +++++
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 75750870..f8725786 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -161,6 +161,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
 	spin_lock_init(&bat_priv->tt.commit_lock);
 	spin_lock_init(&bat_priv->gw.list_lock);
 #ifdef CONFIG_BATMAN_ADV_MCAST
+	spin_lock_init(&bat_priv->mcast.mla_lock);
 	spin_lock_init(&bat_priv->mcast.want_lists_lock);
 #endif
 	spin_lock_init(&bat_priv->tvlv.container_list_lock);
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
index f91b1b62..1b985ab8 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -325,8 +325,6 @@ static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)
  * translation table except the ones listed in the given mcast_list.
  *
  * If mcast_list is NULL then all are retracted.
- *
- * Do not call outside of the mcast worker! (or cancel mcast worker first)
  */
 static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
 					struct hlist_head *mcast_list)
@@ -334,8 +332,6 @@ static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
 	struct batadv_hw_addr *mcast_entry;
 	struct hlist_node *tmp;
 
-	WARN_ON(delayed_work_pending(&bat_priv->mcast.work));
-
 	hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
 				  list) {
 		if (mcast_list &&
@@ -359,8 +355,6 @@ static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
  *
  * Adds multicast listener announcements from the given mcast_list to the
  * translation table if they have not been added yet.
- *
- * Do not call outside of the mcast worker! (or cancel mcast worker first)
  */
 static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
 				    struct hlist_head *mcast_list)
@@ -368,8 +362,6 @@ static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
 	struct batadv_hw_addr *mcast_entry;
 	struct hlist_node *tmp;
 
-	WARN_ON(delayed_work_pending(&bat_priv->mcast.work));
-
 	if (!mcast_list)
 		return;
 
@@ -658,7 +650,10 @@ static void batadv_mcast_mla_update(struct work_struct *work)
 	priv_mcast = container_of(delayed_work, struct batadv_priv_mcast, work);
 	bat_priv = container_of(priv_mcast, struct batadv_priv, mcast);
 
+	spin_lock(&bat_priv->mcast.mla_lock);
 	__batadv_mcast_mla_update(bat_priv);
+	spin_unlock(&bat_priv->mcast.mla_lock);
+
 	batadv_mcast_start_timer(bat_priv);
 }
 
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index a21b34ed..ed0f6a51 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1224,6 +1224,11 @@ struct batadv_priv_mcast {
 	unsigned char bridged:1;
 
 	/**
+	 * @mla_lock: a lock protecting mla_list and mla_flags
+	 */
+	spinlock_t mla_lock;
+
+	/**
 	 * @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP
 	 *  traffic
 	 */



More information about the commits mailing list