[SRU][J][PATCH 1/1] UBUNTU: SAUCE: netfilter: nf_tables: Fix EBUSY on deleting unreferenced chain

Ian Whitfield ian.whitfield at canonical.com
Fri Dec 6 21:29:53 UTC 2024


BugLink: https://bugs.launchpad.net/bugs/2089699

Our backport of upstream commit e79b47a8615d introduced a bug in the
reference counting of chains in nf_tables that resulted in some valid
chain deletion transactions to fail with the error "Error: Could not
process rule: Device or resource busy". This bug is not present in
the upstream stable backport to linux-6.6.y, commit 164936b2fc88.

To resolve the bug, this commit modifies our backport to match commit
164936b2fc88883341fe7a2d9c42b69020e5cafd in linux-6.6.y

Fixes: 08950d766e8b ("netfilter: nf_tables: restore set elements when delete set fails")
Signed-off-by: Ian Whitfield <ian.whitfield at canonical.com>
---
 net/netfilter/nf_tables_api.c  | 10 +++++-----
 net/netfilter/nft_set_pipapo.c |  1 -
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 6940b72ec45b..a03df716c9bc 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -594,7 +594,7 @@ static int nft_mapelem_deactivate(const struct nft_ctx *ctx,
 				  const struct nft_set_iter *iter,
 				  struct nft_set_elem *elem)
 {
-	struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
+	struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	if (!nft_set_elem_active(ext, iter->genmask))
 		return 0;
@@ -5040,7 +5040,7 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
 					const struct nft_set_iter *iter,
 					struct nft_set_elem *elem)
 {
-	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	if (!nft_set_elem_active(ext, iter->genmask))
 		return 0;
@@ -5139,7 +5139,7 @@ static int nft_mapelem_activate(const struct nft_ctx *ctx,
 				const struct nft_set_iter *iter,
 				struct nft_set_elem *elem)
 {
-	struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
+	struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	/* called from abort path, reverse check to undo changes. */
 	if (nft_set_elem_active(ext, iter->genmask))
@@ -5164,8 +5164,8 @@ static void nft_map_catchall_activate(const struct nft_ctx *ctx,
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
-		elem.priv = catchall->elem;
 		nft_clear(ctx->net, ext);
+		elem.priv = catchall->elem;
 		nft_setelem_data_activate(ctx->net, set, &elem);
 		break;
 	}
@@ -6799,7 +6799,7 @@ static int nft_setelem_flush(const struct nft_ctx *ctx,
 			     const struct nft_set_iter *iter,
 			     struct nft_set_elem *elem)
 {
-	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 	struct nft_trans *trans;
 	int err;
 
diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
index 3be88f172740..100ebb7c4b2a 100644
--- a/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -2073,7 +2073,6 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set,
 
 		e = f->mt[r].e;
 
-
 		elem.priv = e;
 
 		iter->err = iter->fn(ctx, set, iter, &elem);
-- 
2.43.0




More information about the kernel-team mailing list