From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 729DD2EF652; Thu, 28 May 2026 20:38:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780000718; cv=none; b=qkCoM7CAQdn1fCGzETOWlTJzBUtj/EQgKQD2P/J+5li2NGeoiaSlfD67whGln+HL2d4OQINmSNOqhZfIok316wKN7FSrQrHq7z+qFe1D8XknYhiyieZKXuHrO1L3dirGzNyRHMvzC6UqSYRLI2YOyDUURJQ5ocu3PbR1nfxICMs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780000718; c=relaxed/simple; bh=RJKuJzUbdP/p9W01/m+2+UESxPUm0SjVXVuvBV1BYCo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e7qBRH9rMBXfqG5bn11PCHSvRwGGx48iAZ4tN8m914O7gWq89zNrO4msabv1H0+hosAb826xLKha9wF6h8i0r/662DpjPVZqUAgOZRqXISQKmWUJZApjNWvndd5YGrXAz9D/AN6s2Tca3qOJ+g7MONkWlSZK2otPeAC09TyqkdY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=2bb2YFTi; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="2bb2YFTi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CFEB51F000E9; Thu, 28 May 2026 20:38:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1780000717; bh=fuCj18+mO35C9VO+NjvT+A2TCgn4+sBActckMC3PiSg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=2bb2YFTiD/P7PP3tjMA0rfUNFHVtzSWmZ2NP7JfMmorGO6DlmoRQH7SEtegQYBQJ4 BDRiIIU2qWayUWh+zyzHDI/WVdW7BR9K3VrGJuAf4o9AJqQFZaMmoesigQ3U4fIr+d Glnur0z78NYx23qVpapq68vTwHMEOIKBKy4x2fKE= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, stable@kernel.org, Simon Wunderlich , Sven Eckelmann Subject: [PATCH 6.12 127/272] batman-adv: bla: fix report_work leak on backbone_gw purge Date: Thu, 28 May 2026 21:48:21 +0200 Message-ID: <20260528194632.936482617@linuxfoundation.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260528194629.379955525@linuxfoundation.org> References: <20260528194629.379955525@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sven Eckelmann commit 0459430add32ea41f3e2ef9351610e6d33627a6b upstream. 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. Cc: stable@kernel.org Fixes: 23721387c409 ("batman-adv: add basic bridge loop avoidance code") Reviewed-by: Simon Wunderlich Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- net/batman-adv/bridge_loop_avoidance.c | 60 ++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 22 deletions(-) --- 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 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,45 @@ static void batadv_bla_purge_backbone_gw 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; - - batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv, - "%s(): backbone gw %pM timed out\n", - __func__, backbone_gw->orig); + do { + purged = false; + + 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); - - 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); + 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); + + 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); } }