* [PATCH RFC batadv] batman-adv: bla: fix report_work leak on backbone_gw purge
@ 2026-05-10 10:03 Sven Eckelmann
2026-05-12 12:09 ` Simon Wunderlich
0 siblings, 1 reply; 2+ messages in thread
From: Sven Eckelmann @ 2026-05-10 10:03 UTC (permalink / raw)
To: b.a.t.m.a.n; +Cc: sw, Sven Eckelmann
batadv_bla_purge_backbone_gw() removes stale backbone gateway entries,
but fails to properly handle their associated report_work:
- If report_work is running, the purge must wait for it to finish before
freeing the backbone_gw, otherwise the worker may access freed memory
(e.g. bat_priv).
- If report_work is pending, the purge must cancel it and release the
reference held for that pending work item.
The previous implementation called hlist_for_each_entry_safe() inside a
spin_lock_bh() section, but cancel_work_sync() may sleep and therefore
cannot be called from within a spinlock-protected region.
Restructure the loop to handle one entry per spinlock critical section:
acquire the lock, find the next entry to purge, remove it from the hash
list, then release the lock before calling cancel_work_sync() and
dropping the hash_entry reference. Repeat until no more entries require
purging.
Fixes: a998bf5dfbd7 ("batman-adv: add detection for complex bridge loops")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
See
https://sashiko.dev/#/patchset/20260508154314.12817-1-sw@simonwunderlich.de?part=7
---
net/batman-adv/bridge_loop_avoidance.c | 53 ++++++++++++++++++++++------------
1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index cec11f12..ff2097eb 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1224,6 +1224,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
struct hlist_head *head;
struct batadv_hashtable *hash;
spinlock_t *list_lock; /* protects write access to the hash lists */
+ bool purged;
int i;
hash = bat_priv->bla.backbone_hash;
@@ -1234,30 +1235,44 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
head = &hash->table[i];
list_lock = &hash->list_locks[i];
- spin_lock_bh(list_lock);
- hlist_for_each_entry_safe(backbone_gw, node_tmp,
- head, hash_entry) {
- if (now)
- goto purge_now;
- if (!batadv_has_timed_out(backbone_gw->lasttime,
- BATADV_BLA_BACKBONE_TIMEOUT))
- continue;
+ do {
+ purged = false;
- batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
- "%s(): backbone gw %pM timed out\n",
- __func__, backbone_gw->orig);
+ spin_lock_bh(list_lock);
+ hlist_for_each_entry_safe(backbone_gw, node_tmp,
+ head, hash_entry) {
+ if (now)
+ goto purge_now;
+ if (!batadv_has_timed_out(backbone_gw->lasttime,
+ BATADV_BLA_BACKBONE_TIMEOUT))
+ continue;
+
+ batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
+ "%s(): backbone gw %pM timed out\n",
+ __func__, backbone_gw->orig);
purge_now:
- /* don't wait for the pending request anymore */
- if (atomic_read(&backbone_gw->request_sent))
- atomic_dec(&bat_priv->bla.num_requests);
+ purged = true;
+ /* don't wait for the pending request anymore */
+ if (atomic_read(&backbone_gw->request_sent))
+ atomic_dec(&bat_priv->bla.num_requests);
- batadv_bla_del_backbone_claims(backbone_gw);
+ batadv_bla_del_backbone_claims(backbone_gw);
- hlist_del_rcu(&backbone_gw->hash_entry);
- batadv_backbone_gw_put(backbone_gw);
- }
- spin_unlock_bh(list_lock);
+ hlist_del_rcu(&backbone_gw->hash_entry);
+ break;
+ }
+ spin_unlock_bh(list_lock);
+
+ if (purged) {
+ /* reference for pending report_work */
+ if (cancel_work_sync(&backbone_gw->report_work))
+ batadv_backbone_gw_put(backbone_gw);
+
+ /* reference for hash_entry */
+ batadv_backbone_gw_put(backbone_gw);
+ }
+ } while (purged);
}
}
---
base-commit: 05abe1217c5104b3514ef1945dacf511b012b921
change-id: 20260510-bla-cancel-work-8dc6f3c2cb14
Best regards,
--
Sven Eckelmann <sven@narfation.org>
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH RFC batadv] batman-adv: bla: fix report_work leak on backbone_gw purge
2026-05-10 10:03 [PATCH RFC batadv] batman-adv: bla: fix report_work leak on backbone_gw purge Sven Eckelmann
@ 2026-05-12 12:09 ` Simon Wunderlich
0 siblings, 0 replies; 2+ messages in thread
From: Simon Wunderlich @ 2026-05-12 12:09 UTC (permalink / raw)
To: b.a.t.m.a.n, Sven Eckelmann
On Sunday, May 10, 2026 12:03:42 PM Central European Summer Time Sven
Eckelmann wrote:
> batadv_bla_purge_backbone_gw() removes stale backbone gateway entries,
> but fails to properly handle their associated report_work:
>
> - If report_work is running, the purge must wait for it to finish before
> freeing the backbone_gw, otherwise the worker may access freed memory
> (e.g. bat_priv).
> - If report_work is pending, the purge must cancel it and release the
> reference held for that pending work item.
>
> The previous implementation called hlist_for_each_entry_safe() inside a
> spin_lock_bh() section, but cancel_work_sync() may sleep and therefore
> cannot be called from within a spinlock-protected region.
>
> Restructure the loop to handle one entry per spinlock critical section:
> acquire the lock, find the next entry to purge, remove it from the hash
> list, then release the lock before calling cancel_work_sync() and
> dropping the hash_entry reference. Repeat until no more entries require
> purging.
>
> Fixes: a998bf5dfbd7 ("batman-adv: add detection for complex bridge loops")
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
This looks good, thank you!
Reviewed-by: Simon Wunderlich <sw@simonwunderlich.de>
Cheers,
Simon
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-05-12 12:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-10 10:03 [PATCH RFC batadv] batman-adv: bla: fix report_work leak on backbone_gw purge Sven Eckelmann
2026-05-12 12:09 ` Simon Wunderlich
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.