summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2026-05-06 23:20:51 +0300
committerSven Eckelmann <sven@narfation.org>2026-05-08 15:28:56 +0300
commitcf6b604011591865ae39ac82de8978c1120d17af (patch)
tree025b0f78e45e5788e56c569bf308568cd8a6ba74
parent4ae1709a314060a196981b344610d023ea841e57 (diff)
downloadlinux-cf6b604011591865ae39ac82de8978c1120d17af.tar.xz
batman-adv: bla: only purge non-released claims
When batadv_bla_purge_claims() goes through the list of claims, it is only traversing the hash list with an rcu_read_lock(). Due to a potential parallel batadv_claim_put(), it can happen that it encounters a claim which was actually in the process of being released+freed by batadv_claim_release(). In this case, backbone_gw is set to NULL before the delayed RCU kfree is started. Calling batadv_bla_claim_get_backbone_gw() is then no longer allowed because it would cause a NULL-ptr derefence. To avoid this, only claims with a valid reference counter must be purged. All others are already taken care of. Cc: stable@kernel.org Fixes: 23721387c409 ("batman-adv: add basic bridge loop avoidance code") Signed-off-by: Sven Eckelmann <sven@narfation.org>
-rw-r--r--net/batman-adv/bridge_loop_avoidance.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 8b77dd2ecfa4..879ab043d57a 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1288,6 +1288,13 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv,
rcu_read_lock();
hlist_for_each_entry_rcu(claim, head, hash_entry) {
+ /* only purge claims not currently in the process of being released.
+ * Such claims could otherwise have a NULL-ptr backbone_gw set because
+ * they already went through batadv_claim_release()
+ */
+ if (!kref_get_unless_zero(&claim->refcount))
+ continue;
+
backbone_gw = batadv_bla_claim_get_backbone_gw(claim);
if (now)
goto purge_now;
@@ -1313,6 +1320,7 @@ purge_now:
claim->addr, claim->vid);
skip:
batadv_backbone_gw_put(backbone_gw);
+ batadv_claim_put(claim);
}
rcu_read_unlock();
}