Skip to content

Conversation

@pvts-mat
Copy link
Contributor

@pvts-mat pvts-mat commented Jan 5, 2026

[LTS 9.2]
CVE-2024-27017 VULN-37652
CVE-2024-27012 VULN-37622

About

This PR is a continuation of the netfilter patch set bugfixes (see also #794). The CVE-2024-27012 fix required relatively wide conflicts resolution which warranted this separate PR to ease the review process. Additionally the backport of 29b359c was included, which was associated with its own CVE-2024-27017.

These two fixes conclude the bugfixing of #668.

Commits

netfilter: nft_set_pipapo: walk over current view on netlink dump

jira VULN-37652
cve CVE-2024-27017
commit-author Pablo Neira Ayuso <pablo@netfilter.org>
commit 29b359cf6d95fd60730533f7f10464e95bd17c73
upstream-diff Resolved conflicts in the declarations block in
  nft_pipapo_walk() function. No actual diffs in the end.
netfilter: nf_tables: missing iterator type in lookup walk

jira VULN-37652
cve-bf CVE-2024-27017
commit-author Pablo Neira Ayuso <pablo@netfilter.org>
commit b6603321a74c6371ed1db05e5cfac0623ada8d5d
netfilter: nf_tables: restore set elements when delete set fails

jira VULN-37622
cve CVE-2024-27012
commit-author Pablo Neira Ayuso <pablo@netfilter.org>
commit e79b47a8615d42c68aaeb68971593333667382ed
upstream-diff Accounted for the missing commit
  0e1ea651c9717ddcd8e0648d8468477a31867b0a.

Although cherry-picking e79b47a resulted in many conflicts they all had a single source - the lack of backported 0e1ea65 netfilter: nf_tables: shrink memory consumption of set elements. The CentOS 9 backport 03c356c was not useful, since the 9.6 version it was commited to had that prerequisite in place. The resolved version turned out to be very similar to the linux-6.6.y backport 164936b.

kABI check: passed

[2/5] kabi_check_kernel	Check ABI of kernel [ciqlts9_2-CVE-batch-15]	_kabi_check_kernel__x86_64--test--ciqlts9_2-CVE-batch-15
++ uname -m
+ python3 /data/src/ctrliq-github-haskell/kernel-dist-git-el-9.2/SOURCES/check-kabi -k /data/src/ctrliq-github-haskell/kernel-dist-git-el-9.2/SOURCES/Module.kabi_x86_64 -s vms/x86_64--build--ciqlts9_2/build_files/kernel-src-tree-ciqlts9_2-CVE-batch-15/Module.symvers
kABI check passed
+ touch state/kernels/ciqlts9_2-CVE-batch-15/x86_64/kabi_checked

Boot test: passed

boot-test.log

Kselftests: passed

Reference

kselftests–ciqlts9_2–run1.log
kselftests–ciqlts9_2–run2.log

Patch

kselftests–ciqlts9_2-CVE-batch-15–run1.log
kselftests–ciqlts9_2-CVE-batch-15–run2.log
kselftests–ciqlts9_2-CVE-batch-15–run3.log

Comparison

The tests results for the reference and the patch are the same.

$ ktests.xsh diff  kselftests*.log

Column    File
--------  --------------------------------------------
Status0   kselftests--ciqlts9_2--run1.log
Status1   kselftests--ciqlts9_2--run2.log
Status2   kselftests--ciqlts9_2-CVE-batch-15--run1.log
Status3   kselftests--ciqlts9_2-CVE-batch-15--run2.log
Status4   kselftests--ciqlts9_2-CVE-batch-15--run3.log

TestCase                              Status0  Status1  Status2  Status3  Status4  Summary
netfilter:conntrack_icmp_related.sh   pass     pass     pass     pass     pass     same
netfilter:conntrack_tcp_unreplied.sh  pass     pass     pass     pass     pass     same
netfilter:conntrack_vrf.sh            pass     pass     pass     pass     pass     same
netfilter:ipip-conntrack-mtu.sh       pass     pass     pass     pass     pass     same
netfilter:ipvs.sh                     pass     pass     pass     pass     pass     same
netfilter:nf_nat_edemux.sh            pass     pass     pass     pass     pass     same
netfilter:nft_conntrack_helper.sh     pass     pass     pass     pass     pass     same
netfilter:nft_fib.sh                  pass     pass     pass     pass     pass     same
netfilter:nft_meta.sh                 pass     pass     pass     pass     pass     same
netfilter:nft_nat.sh                  pass     pass     pass     pass     pass     same
netfilter:nft_queue.sh                pass     pass     pass     pass     pass     same
netfilter:rpath.sh                    pass     pass     pass     pass     pass     same

Copy link
Contributor

@roxanan1996 roxanan1996 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit "netfilter: nf_tables: missing iterator type in lookup walk" (2nd)
references upstream commit b6603321a74c6371ed1db05e5cfac0623ada8d5d
but this does not exist. Commit efefd4f is the right one here.
Also, was this a clean patch? I believe you ran into the same conflict as for the previous commit.

Otherwise, the patches looked correct.

@pvts-mat pvts-mat force-pushed the ciqlts9_2-CVE-batch-15 branch from a40b32d to 233bfe0 Compare January 5, 2026 14:01
@pvts-mat
Copy link
Contributor Author

pvts-mat commented Jan 5, 2026

Commit "netfilter: nf_tables: missing iterator type in lookup walk" (2nd) references upstream commit b6603321a74c6371ed1db05e5cfac0623ada8d5d but this does not exist. Commit efefd4f is the right one here. Also, was this a clean patch? I believe you ran into the same conflict as for the previous commit.

Otherwise, the patches looked correct.

Yes, sorry for the mistake.

I will look into ciq-cherry-pick.py to expand it a bit because I find myself having to avoid it more often than not whenever there is a deviation from the most typical patching flow. This data can't be managed by hand, clearly.

The pick was clean in my repo. You experienced some conflicts? Can you share?

@pvts-mat pvts-mat requested a review from roxanan1996 January 5, 2026 14:20
@roxanan1996
Copy link
Contributor

roxanan1996 commented Jan 5, 2026

Commit "netfilter: nf_tables: missing iterator type in lookup walk" (2nd) references upstream commit b6603321a74c6371ed1db05e5cfac0623ada8d5d but this does not exist. Commit efefd4f is the right one here. Also, was this a clean patch? I believe you ran into the same conflict as for the previous commit.
Otherwise, the patches looked correct.

Yes, sorry for the mistake.

I will look into ciq-cherry-pick.py to expand it a bit because I find myself having to avoid it more often than not whenever there is a deviation from the most typical patching flow. This data can't be managed by hand, clearly.

Would you mind sharing your pain points with it? Because I am also working on extending it and it would be beneficial to include your workflow as well. Thanks!

The pick was clean in my repo. You experienced some conflicts? Can you share?

I just assumed that by looking at the patch. Forgot about the 3way merge. All good.

@pvts-mat
Copy link
Contributor Author

pvts-mat commented Jan 5, 2026

Would you mind sharing your pain points with it? Because I am also working on extending it and it would be beneficial to include your workflow as well. Thanks!

When composing the final patch I often re-arrange the commits and cherry-pick my own ones with the conflicts already resolved to not have to resolve them again or deal with patches. Other than that there is often a need to use different bases than the upstream, like linux stable branches or CentOS backports. Sometimes I create the commit manually, by editing the files or copying them from some source.

The way I see it is that ciq-cherry-pick.py should aim to have the meta-data of a commit aligned with specific rules of CIQ bookkeeping. Currently this logic is coupled with the way the change is obtained - cherry picking a commit from the upstream. The ideal tool would set this data independently from how the commit was actually obtained. The most often used methods could be integrated into the tool to streamline the process but it should be treated as a bonus, not ciq-cherry-pick.py's responsibility to cover them all. So in a way I wouldn't want my workflows to be included, but to have a tool for which they're irrelevant.

The lowest hanging fruit I guess would be to decouple the body message composition from the operation on git repository. Just printing the message for the user to copy into the commit of his/her own making.

roxanan1996
roxanan1996 previously approved these changes Jan 6, 2026
Copy link
Contributor

@roxanan1996 roxanan1996 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to update your branch to include the latest changes of 9.2 to pass the pr checks. https://github.com/ctrliq/kernel-src-tree/actions/runs/20717747278/job/59476706444?pr=798

Otherwise, it looks good to me.

@pvts-mat pvts-mat force-pushed the ciqlts9_2-CVE-batch-15 branch from 233bfe0 to ca81e12 Compare January 7, 2026 16:36
@github-actions
Copy link

github-actions bot commented Jan 7, 2026

🤖 Validation Checks In Progress Workflow run: https://github.com/ctrliq/kernel-src-tree/actions/runs/20795793676

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

🔍 Interdiff Analysis

  • ⚠️ PR commit 75368c09c37 (netfilter: nft_set_pipapo: walk over current view on netlink dump) → upstream 29b359cf6d95
    Differences found:
diff -u b/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
--- b/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5475,5 +5475,5 @@
+	args.cb			= cb;
 	args.skb		= skb;
-	args.reset		= dump_ctx->reset;
 	args.iter.genmask	= nft_genmask_cur(net);
 	args.iter.type		= NFT_ITER_READ;
 	args.iter.skip		= cb->args[0];
diff -u b/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
--- b/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -2018,9 +2018,9 @@
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
 	struct net *net = read_pnet(&set->net);
-	const struct nft_pipapo_match *m;
-	const struct nft_pipapo_field *f;
-	unsigned int i, r;
+	struct nft_pipapo_match *m;
+	struct nft_pipapo_field *f;
+	int i, r;
 
 	rcu_read_lock();
 	if (iter->type == NFT_ITER_READ)
@@ -2021,8 +2021,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 			    struct nft_set_iter *iter)
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
-	struct net *net = read_pnet(&set->net);
 	struct nft_pipapo_match *m;
 	struct nft_pipapo_field *f;
 	int i, r;
 
@@ -2026,6 +2025,8 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 	struct nft_pipapo_field *f;
 	int i, r;
 
+	WARN_ON_ONCE(iter->type == NFT_ITER_UNSPEC);
+
 	rcu_read_lock();
 	if (iter->genmask == nft_genmask_cur(net))
 		m = rcu_dereference(priv->match);
@@ -2115,8 +2115,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 			    struct nft_set_iter *iter)
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
-	struct net *net = read_pnet(&set->net);
 	const struct nft_pipapo_match *m;
 	const struct nft_pipapo_field *f;
 	unsigned int i, r;
 
@@ -2120,6 +2119,8 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 	const struct nft_pipapo_field *f;
 	unsigned int i, r;
 
+	WARN_ON_ONCE(iter->type == NFT_ITER_UNSPEC);
+
 	rcu_read_lock();
 	if (iter->genmask == nft_genmask_cur(net))
 		m = rcu_dereference(priv->match);
  • ⚠️ PR commit 55464e204b9 (netfilter: nf_tables: missing iterator type in lookup walk) → upstream efefd4f00c96
    Differences found:
diff -u b/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
--- b/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -2022,5 +2022,5 @@
-	const struct nft_pipapo_field *f;
-	unsigned int i, r;
+	struct nft_pipapo_field *f;
+	int i, r;
 
 	WARN_ON_ONCE(iter->type != NFT_ITER_READ &&
 		     iter->type != NFT_ITER_UPDATE);
  • ⚠️ PR commit ca81e125bd5 (netfilter: nf_tables: restore set elements when delete set fails) → upstream e79b47a8615d
    Differences found:
diff -u b/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
--- b/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -590,6 +590,6 @@
 				  const struct nft_set_iter *iter,
-				  struct nft_elem_priv *elem_priv)
+				  struct nft_set_elem *elem)
 {
-	nft_setelem_data_deactivate(ctx->net, set, elem_priv);
+	nft_setelem_data_deactivate(ctx->net, set, elem);
 
 	return 0;
@@ -593,6 +593,12 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 				  const struct nft_set_iter *iter,
 				  struct nft_set_elem *elem)
 {
+	struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
+	nft_set_elem_change_active(ctx->net, set, ext);
 	nft_setelem_data_deactivate(ctx->net, set, elem);
 
 	return 0;
@@ -594,6 +594,12 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 				  const struct nft_set_iter *iter,
 				  struct nft_elem_priv *elem_priv)
 {
+	struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
+
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
+	nft_set_elem_change_active(ctx->net, set, ext);
 	nft_setelem_data_deactivate(ctx->net, set, elem_priv);
 
 	return 0;
@@ -614,6 +613,6 @@
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
-		nft_setelem_data_deactivate(ctx->net, set, catchall->elem);
+		elem.priv = catchall->elem;
+		nft_setelem_data_deactivate(ctx->net, set, &elem);
 		break;
-	}
@@ -617,6 +623,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
+		nft_set_elem_change_active(ctx->net, set, ext);
 		elem.priv = catchall->elem;
 		nft_setelem_data_deactivate(ctx->net, set, &elem);
 		break;
@@ -617,6 +623,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
+		nft_set_elem_change_active(ctx->net, set, ext);
 		nft_setelem_data_deactivate(ctx->net, set, catchall->elem);
 		break;
 	}
@@ -3516,15 +3516,16 @@
 		.genmask	= nft_genmask_next(ctx->net),
 	};
 	struct nft_set_elem_catchall *catchall;
+	struct nft_set_elem elem;
 	struct nft_set_ext *ext;
-	int ret = 0;
 
 	list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
 		ext = nft_set_elem_ext(set, catchall->elem);
-		if (!nft_set_elem_active(ext, dummy_iter.genmask))
+		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
-		ret = nft_setelem_validate(ctx, set, NULL, catchall->elem);
+		elem.priv = catchall->elem;
+		ret = nft_setelem_validate(ctx, set, NULL, &elem);
 		if (ret < 0)
 			return ret;
 	}
@@ -3526,7 +3538,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 			continue;
 
 		elem.priv = catchall->elem;
-		ret = nft_setelem_validate(ctx, set, NULL, &elem);
+		ret = nft_setelem_validate(ctx, set, &dummy_iter, &elem);
 		if (ret < 0)
 			return ret;
 	}
@@ -3910,8 +3922,9 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 {
 	u8 genmask = nft_genmask_next(ctx->net);
 	struct nft_set_elem_catchall *catchall;
+
 	struct nft_set_ext *ext;
 	int ret = 0;
 
 	list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
 		ext = nft_set_elem_ext(set, catchall->elem);
@@ -3915,7 +3928,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 
 	list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
 		ext = nft_set_elem_ext(set, catchall->elem);
-		if (!nft_set_elem_active(ext, genmask))
+		if (!nft_set_elem_active(ext, dummy_iter.genmask))
 			continue;
 
 		ret = nft_setelem_validate(ctx, set, NULL, catchall->elem);
@@ -3918,7 +3931,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
-		ret = nft_setelem_validate(ctx, set, NULL, catchall->elem);
+		ret = nft_setelem_validate(ctx, set, &dummy_iter, catchall->elem);
 		if (ret < 0)
 			return ret;
 	}
@@ -5003,6 +5015,11 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 					const struct nft_set_iter *iter,
 					struct nft_set_elem *elem)
 {
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
 	return nft_setelem_data_validate(ctx, set, elem);
 }
 
@@ -5097,6 +5114,13 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 				const struct nft_set_iter *iter,
 				struct nft_set_elem *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))
+		return 0;
+
+	nft_clear(ctx->net, ext);
 	nft_setelem_data_activate(ctx->net, set, elem);
 
 	return 0;
@@ -5115,6 +5139,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
+		nft_clear(ctx->net, ext);
 		elem.priv = catchall->elem;
 		nft_setelem_data_activate(ctx->net, set, &elem);
 		break;
@@ -5387,6 +5412,9 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 	struct nft_set_dump_args *args;
 
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
 	if (nft_set_elem_expired(ext))
 		return 0;
 
@@ -5407,6 +5420,11 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 					const struct nft_set_iter *iter,
 					struct nft_elem_priv *elem_priv)
 {
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
+
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
 	return nft_setelem_data_validate(ctx, set, elem_priv);
 }
 
@@ -5499,6 +5517,13 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 				const struct nft_set_iter *iter,
 				struct nft_elem_priv *elem_priv)
 {
+	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))
+		return 0;
+
+	nft_clear(ctx->net, ext);
 	nft_setelem_data_activate(ctx->net, set, elem_priv);
 
 	return 0;
@@ -5516,6 +5541,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
+		nft_clear(ctx->net, ext);
 		nft_setelem_data_activate(ctx->net, set, catchall->elem);
 		break;
 	}
@@ -5790,6 +5816,9 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
 	struct nft_set_dump_args *args;
 
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
 	if (nft_set_elem_expired(ext) || nft_set_elem_is_dead(ext))
 		return 0;
 
@@ -6120,7 +6148,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 	struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	if (nft_setelem_is_catchall(set, elem)) {
-		nft_set_elem_change_active(net, set, ext);
+		nft_clear(net, ext);
 	} else {
 		set->ops->activate(net, set, elem);
 	}
@@ -6640,7 +6669,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 	struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
 
 	if (nft_setelem_is_catchall(set, elem_priv)) {
-		nft_set_elem_change_active(net, set, ext);
+		nft_clear(net, ext);
 	} else {
 		set->ops->activate(net, set, elem_priv);
 	}
@@ -6792,7 +6792,7 @@
 			     const struct nft_set_iter *iter,
-			     struct nft_elem_priv *elem_priv)
+			     struct nft_set_elem *elem)
 {
-	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
 	struct nft_trans *trans;
 
 	if (!nft_set_elem_active(ext, iter->genmask))
@@ -10061,5 +10061,5 @@
 {
-	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	if (!nft_set_elem_active(ext, iter->genmask))
 		return 0;
diff -u b/net/netfilter/nft_set_bitmap.c b/net/netfilter/nft_set_bitmap.c
--- b/net/netfilter/nft_set_bitmap.c
+++ b/net/netfilter/nft_set_bitmap.c
@@ -227,3 +227,3 @@
 
-		iter->err = iter->fn(ctx, set, iter, &be->priv);
+		elem.priv = &be->priv;
 
diff -u b/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
--- b/net/netfilter/nft_set_hash.c
+++ b/net/netfilter/nft_set_hash.c
@@ -192,5 +192,5 @@
 {
-	struct nft_rhash_elem *he = nft_elem_priv_cast(elem_priv);
+	struct nft_rhash_elem *he = nft_elem_priv_cast(elem->priv);
 
 	nft_clear(net, &he->ext);
 }
@@ -282,5 +282,5 @@
 		if (iter->count < iter->skip)
 			goto cont;
 
-		iter->err = iter->fn(ctx, set, iter, &he->priv);
-		if (iter->err < 0)
+		elem.priv = &he->priv;
+
@@ -592,5 +592,5 @@
 {
-	struct nft_hash_elem *he = nft_elem_priv_cast(elem_priv);
+	struct nft_hash_elem *he = nft_elem_priv_cast(elem->priv);
 
 	nft_clear(net, &he->ext);
 }
@@ -649,5 +649,5 @@
 			if (iter->count < iter->skip)
 				goto cont;
 
-			iter->err = iter->fn(ctx, set, iter, &he->priv);
-			if (iter->err < 0)
+			elem.priv = &he->priv;
+
diff -u b/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
--- b/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -1752,5 +1752,5 @@
 {
-	struct nft_pipapo_elem *e = nft_elem_priv_cast(elem_priv);
+	struct nft_pipapo_elem *e = nft_elem_priv_cast(elem->priv);
 
 	nft_clear(net, &e->ext);
 }
@@ -2049,9 +2049,9 @@
 
 		e = f->mt[r].e;
 
 		if (!nft_set_elem_active(&e->ext, iter->genmask))
 			goto cont;
 
-		iter->err = iter->fn(ctx, set, iter, &e->priv);
-		if (iter->err < 0)
-			goto out;
+		elem.priv = &e->priv;
+
+		iter->err = iter->fn(ctx, set, iter, &elem);
@@ -2052,9 +2052,6 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 
 		e = f->mt[r].e;
 
-		if (!nft_set_elem_active(&e->ext, iter->genmask))
-			goto cont;
-
 		elem.priv = &e->priv;
 
 		iter->err = iter->fn(ctx, set, iter, &elem);
@@ -2149,9 +2149,6 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 
 		e = f->mt[r].e;
 
-		if (!nft_set_elem_active(&e->ext, iter->genmask))
-			goto cont;
-
 		iter->err = iter->fn(ctx, set, iter, &e->priv);
 		if (iter->err < 0)
 			goto out;
diff -u b/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
--- b/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -528,5 +528,5 @@
 {
-	struct nft_rbtree_elem *rbe = nft_elem_priv_cast(elem_priv);
+	struct nft_rbtree_elem *rbe = nft_elem_priv_cast(elem->priv);
 
 	nft_clear(net, &rbe->ext);
 }
@@ -597,5 +597,5 @@
 		if (iter->count < iter->skip)
 			goto cont;
 
-		iter->err = iter->fn(ctx, set, iter, &rbe->priv);
-		if (iter->err < 0) {
+		elem.priv = &rbe->priv;
+

This is an automated interdiff check for backported commits.

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

JIRA PR Check Results

3 commit(s) with issues found:

Commit ca81e125bd5c

Summary: netfilter: nf_tables: restore set elements when delete set fails

❌ Errors:

  • VULN-37622: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-37622: No time logged - please log time manually

Commit 55464e204b97

Summary: netfilter: nf_tables: missing iterator type in lookup walk

❌ Errors:

  • VULN-37652: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-37652: No time logged - please log time manually

Commit 75368c09c375

Summary: netfilter: nft_set_pipapo: walk over current view on netlink dump

❌ Errors:

  • VULN-37652: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-37652: No time logged - please log time manually

Summary: Checked 3 commit(s) total.

@github-actions
Copy link

github-actions bot commented Jan 7, 2026

Validation checks completed with issues View full results: https://github.com/ctrliq/kernel-src-tree/actions/runs/20795793676

@pvts-mat
Copy link
Contributor Author

pvts-mat commented Jan 8, 2026

@kerneltoast can you help me understand how the interdiff works? I'm trying to integrate it into my workflow and its output often confuses me.

1

Why isn't interdiff's output anti-symmetric on its arguments? I imagine interdiff to be calculating the "delta of deltas" of two revisions, so that would be $$\textnormal{interdiff}(\Delta_1, \Delta_2) = \Delta_2 - \Delta_1 = - (\Delta_1 - \Delta_2) = - \textnormal{interdiff}(\Delta_2, \Delta_1)$$. In many cases this seems to hold true, for example

interdiff --fuzzy=3 \
    <(git format-patch -1 --stdout 7a0da446b3c5308f70db894b02fb696a5176aeff) \
    <(git format-patch -1 --stdout 6b1ca88e4bb63673dc9f9c7f23c899f22c3cb17a)

gives me:

diff -u b/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
--- b/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5376,4 +5376,4 @@
-	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 	struct nft_set_dump_args *args;
 
 	if (nft_set_elem_expired(ext) || nft_set_elem_is_dead(ext))

and the reversed arguments call

interdiff --fuzzy=3 \
    <(git format-patch -1 --stdout 6b1ca88e4bb63673dc9f9c7f23c899f22c3cb17a) \
    <(git format-patch -1 --stdout 7a0da446b3c5308f70db894b02fb696a5176aeff)

gives the reversed output, as expected:

diff -u b/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
--- b/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5715,4 +5715,4 @@
-	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
 	struct nft_set_dump_args *args;
 
 	if (nft_set_elem_expired(ext) || nft_set_elem_is_dead(ext))

However:

  • Case 1
    • Pair 59d9094, 8ce465b: Works fine
    • Pair 8ce465b, 59d9094: Error "Line not understood:" (yet it could have been understood in the other argument?)
  • Case 2
  • Case 3: Both end without error, but produce very different output. Pasting a fragment here

Pair 9ad7974, 44b84d4:

--- b/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -754,18446744073709551602 +754,7 @@
+{
+	unsigned int hlen = ALIGN(extra_headroom, 4);
 	struct sk_buff *frame = NULL;
-	u16 ethertype;
-	u8 *payload;
 	int offset = 0, remaining;
-	struct ethhdr eth;
-	bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
-	bool reuse_skb = false;
-	bool last = false;
+	struct {
+		struct ethhdr eth;
+		uint8_t flags;
[...]

Pair 44b84d4, 9ad7974:

--- b/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -754,7 +754,18446744073709551598 @@
-{
-	unsigned int hlen = ALIGN(extra_headroom, 4);
 	struct sk_buff *frame = NULL;
+	u16 ethertype;
+	u8 *payload;
 	int offset = 0, remaining;
-	struct {
-		struct ethhdr eth;
-		uint8_t flags;
@@ -757,10 +757,10 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 	struct sk_buff *frame = NULL;
 	u16 ethertype;
 	u8 *payload;
-	int offset = 0, remaining;
+	int offset = 0;
 	struct ethhdr eth;
 	bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
 	bool reuse_skb = false;
 	bool last = false;
 
 	while (!last) {
[...]

2

Why does interdiff show differences in both the changes and the contexts of changes instead of just the changes? I realize the information about the differences around the changes themselves may be useful in manual analysis (though I find myself usually filtering it out as noise), however, the interdiff tool is plugged into github actions and is supposed to notify when the changes, and only the changes, differ from the upstream, no? To alert about the deviations, to prompt checking if such differing commit is supplied with the proper upstream-diff for example, etc. What's the role of context differences warnings in the PR?

3

What does INTERDIFF: rejected hunk from patch1, cannot diff context message mean? How to help interdiff diff the context?

4

How does the --fuzz rgument influence the output? I couldn't figure it out.

5

Original interdiff was meant to work on isolated patches, and that's cool, however the git repository contains far more information than what can fit into patch files, like the full file context and its history, the lack of which seems to prevent interdiff from producing useful output in most cases, which was what prompted your work, I suppose. However, you do stick to interdifff and the patches input paradigm, working around the limited info with fuzzy hunk matching, even though we have access to the repo and can leverage its data. I don't know git internals, but I'm guessing that's what git's auto-merging magic leverages already. Wasn't there any existing project which aims for what interdiff poorly tries to achieve, but using a git repository directly? Could it be easier to just fork git and add this feature there instead of investing in interdiff which will always be very limited?

jira VULN-37652
cve CVE-2024-27017
commit-author Pablo Neira Ayuso <pablo@netfilter.org>
commit 29b359c
upstream-diff Resolved conflicts in the declarations block in
  nft_pipapo_walk() function. No actual diffs in the end.

The generation mask can be updated while netlink dump is in progress.
The pipapo set backend walk iterator cannot rely on it to infer what
view of the datastructure is to be used. Add notation to specify if user
wants to read/update the set.

Based on patch from Florian Westphal.

Fixes: 2b84e21 ("netfilter: nft_set_pipapo: .walk does not deal with generations")
	Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit 29b359c)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-37652
cve-bf CVE-2024-27017
commit-author Pablo Neira Ayuso <pablo@netfilter.org>
commit efefd4f

Add missing decorator type to lookup expression and tighten WARN_ON_ONCE
check in pipapo to spot earlier that this is unset.

Fixes: 29b359c ("netfilter: nft_set_pipapo: walk over current view on netlink dump")
	Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit efefd4f)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
jira VULN-37622
cve CVE-2024-27012
commit-author Pablo Neira Ayuso <pablo@netfilter.org>
commit e79b47a
upstream-diff Accounted for the missing commit
  0e1ea65.

From abort path, nft_mapelem_activate() needs to restore refcounters to
the original state. Currently, it uses the set->ops->walk() to iterate
over these set elements. The existing set iterator skips inactive
elements in the next generation, this does not work from the abort path
to restore the original state since it has to skip active elements
instead (not inactive ones).

This patch moves the check for inactive elements to the set iterator
callback, then it reverses the logic for the .activate case which
needs to skip active elements.

Toggle next generation bit for elements when delete set command is
invoked and call nft_clear() from .activate (abort) path to restore the
next generation bit.

The splat below shows an object in mappings memleak:

[43929.457523] ------------[ cut here ]------------
[43929.457532] WARNING: CPU: 0 PID: 1139 at include/net/netfilter/nf_tables.h:1237 nft_setelem_data_deactivate+0xe4/0xf0 [nf_tables]
[...]
[43929.458014] RIP: 0010:nft_setelem_data_deactivate+0xe4/0xf0 [nf_tables]
[43929.458076] Code: 83 f8 01 77 ab 49 8d 7c 24 08 e8 37 5e d0 de 49 8b 6c 24 08 48 8d 7d 50 e8 e9 5c d0 de 8b 45 50 8d 50 ff 89 55 50 85 c0 75 86 <0f> 0b eb 82 0f 0b eb b3 0f 1f 40 00 90 90 90 90 90 90 90 90 90 90
[43929.458081] RSP: 0018:ffff888140f9f4b0 EFLAGS: 00010246
[43929.458086] RAX: 0000000000000000 RBX: ffff8881434f5288 RCX: dffffc0000000000
[43929.458090] RDX: 00000000ffffffff RSI: ffffffffa26d28a7 RDI: ffff88810ecc9550
[43929.458093] RBP: ffff88810ecc9500 R08: 0000000000000001 R09: ffffed10281f3e8f
[43929.458096] R10: 0000000000000003 R11: ffff0000ffff0000 R12: ffff8881434f52a0
[43929.458100] R13: ffff888140f9f5f4 R14: ffff888151c7a800 R15: 0000000000000002
[43929.458103] FS:  00007f0c687c4740(0000) GS:ffff888390800000(0000) knlGS:0000000000000000
[43929.458107] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[43929.458111] CR2: 00007f58dbe5b008 CR3: 0000000123602005 CR4: 00000000001706f0
[43929.458114] Call Trace:
[43929.458118]  <TASK>
[43929.458121]  ? __warn+0x9f/0x1a0
[43929.458127]  ? nft_setelem_data_deactivate+0xe4/0xf0 [nf_tables]
[43929.458188]  ? report_bug+0x1b1/0x1e0
[43929.458196]  ? handle_bug+0x3c/0x70
[43929.458200]  ? exc_invalid_op+0x17/0x40
[43929.458211]  ? nft_setelem_data_deactivate+0xd7/0xf0 [nf_tables]
[43929.458271]  ? nft_setelem_data_deactivate+0xe4/0xf0 [nf_tables]
[43929.458332]  nft_mapelem_deactivate+0x24/0x30 [nf_tables]
[43929.458392]  nft_rhash_walk+0xdd/0x180 [nf_tables]
[43929.458453]  ? __pfx_nft_rhash_walk+0x10/0x10 [nf_tables]
[43929.458512]  ? rb_insert_color+0x2e/0x280
[43929.458520]  nft_map_deactivate+0xdc/0x1e0 [nf_tables]
[43929.458582]  ? __pfx_nft_map_deactivate+0x10/0x10 [nf_tables]
[43929.458642]  ? __pfx_nft_mapelem_deactivate+0x10/0x10 [nf_tables]
[43929.458701]  ? __rcu_read_unlock+0x46/0x70
[43929.458709]  nft_delset+0xff/0x110 [nf_tables]
[43929.458769]  nft_flush_table+0x16f/0x460 [nf_tables]
[43929.458830]  nf_tables_deltable+0x501/0x580 [nf_tables]

Fixes: 628bd3e ("netfilter: nf_tables: drop map element references from preparation phase")
	Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit e79b47a)
	Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
@pvts-mat
Copy link
Contributor Author

pvts-mat commented Jan 9, 2026

This forced push was a rebase onto the latest ciqlts9_2 which had one conflict to resolve after #794 was merged. (Function nf_tables_dump_setelem(), file net/netfilter/nf_tables_api.c, commit netfilter: nf_tables: skip dead set elements in netlink dump vs netfilter: nf_tables: restore set elements when delete set fails)

@github-actions
Copy link

🤖 Validation Checks In Progress Workflow run: https://github.com/ctrliq/kernel-src-tree/actions/runs/20908353549

@github-actions
Copy link

🔍 Interdiff Analysis

  • ⚠️ PR commit 220ae769a52 (netfilter: nft_set_pipapo: walk over current view on netlink dump) → upstream 29b359cf6d95
    Differences found:
diff -u b/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
--- b/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5473,5 +5473,5 @@
+	args.cb			= cb;
 	args.skb		= skb;
-	args.reset		= dump_ctx->reset;
 	args.iter.genmask	= nft_genmask_cur(net);
 	args.iter.type		= NFT_ITER_READ;
 	args.iter.skip		= cb->args[0];
diff -u b/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
--- b/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -2018,9 +2018,9 @@
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
 	struct net *net = read_pnet(&set->net);
-	const struct nft_pipapo_match *m;
-	const struct nft_pipapo_field *f;
-	unsigned int i, r;
+	struct nft_pipapo_match *m;
+	struct nft_pipapo_field *f;
+	int i, r;
 
 	rcu_read_lock();
 	if (iter->type == NFT_ITER_READ)
@@ -2021,8 +2021,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 			    struct nft_set_iter *iter)
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
-	struct net *net = read_pnet(&set->net);
 	struct nft_pipapo_match *m;
 	struct nft_pipapo_field *f;
 	int i, r;
 
@@ -2026,6 +2025,8 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 	struct nft_pipapo_field *f;
 	int i, r;
 
+	WARN_ON_ONCE(iter->type == NFT_ITER_UNSPEC);
+
 	rcu_read_lock();
 	if (iter->genmask == nft_genmask_cur(net))
 		m = rcu_dereference(priv->match);
@@ -2115,8 +2115,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 			    struct nft_set_iter *iter)
 {
 	struct nft_pipapo *priv = nft_set_priv(set);
-	struct net *net = read_pnet(&set->net);
 	const struct nft_pipapo_match *m;
 	const struct nft_pipapo_field *f;
 	unsigned int i, r;
 
@@ -2120,6 +2119,8 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 	const struct nft_pipapo_field *f;
 	unsigned int i, r;
 
+	WARN_ON_ONCE(iter->type == NFT_ITER_UNSPEC);
+
 	rcu_read_lock();
 	if (iter->genmask == nft_genmask_cur(net))
 		m = rcu_dereference(priv->match);
  • ⚠️ PR commit f356abea674 (netfilter: nf_tables: missing iterator type in lookup walk) → upstream efefd4f00c96
    Differences found:
diff -u b/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
--- b/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -2022,5 +2022,5 @@
-	const struct nft_pipapo_field *f;
-	unsigned int i, r;
+	struct nft_pipapo_field *f;
+	int i, r;
 
 	WARN_ON_ONCE(iter->type != NFT_ITER_READ &&
 		     iter->type != NFT_ITER_UPDATE);
  • ⚠️ PR commit 885832033b5 (netfilter: nf_tables: restore set elements when delete set fails) → upstream e79b47a8615d
    Differences found:
diff -u b/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
--- b/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -588,6 +588,6 @@
 				  const struct nft_set_iter *iter,
-				  struct nft_elem_priv *elem_priv)
+				  struct nft_set_elem *elem)
 {
-	nft_setelem_data_deactivate(ctx->net, set, elem_priv);
+	nft_setelem_data_deactivate(ctx->net, set, elem);
 
 	return 0;
@@ -591,6 +591,12 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 				  const struct nft_set_iter *iter,
 				  struct nft_set_elem *elem)
 {
+	struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
+	nft_set_elem_change_active(ctx->net, set, ext);
 	nft_setelem_data_deactivate(ctx->net, set, elem);
 
 	return 0;
@@ -594,6 +594,12 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 				  const struct nft_set_iter *iter,
 				  struct nft_elem_priv *elem_priv)
 {
+	struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
+
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
+	nft_set_elem_change_active(ctx->net, set, ext);
 	nft_setelem_data_deactivate(ctx->net, set, elem_priv);
 
 	return 0;
@@ -614,6 +611,6 @@
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
-		nft_setelem_data_deactivate(ctx->net, set, catchall->elem);
+		elem.priv = catchall->elem;
+		nft_setelem_data_deactivate(ctx->net, set, &elem);
 		break;
-	}
@@ -615,6 +621,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
+		nft_set_elem_change_active(ctx->net, set, ext);
 		elem.priv = catchall->elem;
 		nft_setelem_data_deactivate(ctx->net, set, &elem);
 		break;
@@ -617,6 +623,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
+		nft_set_elem_change_active(ctx->net, set, ext);
 		nft_setelem_data_deactivate(ctx->net, set, catchall->elem);
 		break;
 	}
@@ -3514,15 +3514,16 @@
 		.genmask	= nft_genmask_next(ctx->net),
 	};
 	struct nft_set_elem_catchall *catchall;
+	struct nft_set_elem elem;
 	struct nft_set_ext *ext;
-	int ret = 0;
 
 	list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
 		ext = nft_set_elem_ext(set, catchall->elem);
-		if (!nft_set_elem_active(ext, dummy_iter.genmask))
+		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
-		ret = nft_setelem_validate(ctx, set, NULL, catchall->elem);
+		elem.priv = catchall->elem;
+		ret = nft_setelem_validate(ctx, set, NULL, &elem);
 		if (ret < 0)
 			return ret;
 	}
@@ -3524,7 +3536,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 			continue;
 
 		elem.priv = catchall->elem;
-		ret = nft_setelem_validate(ctx, set, NULL, &elem);
+		ret = nft_setelem_validate(ctx, set, &dummy_iter, &elem);
 		if (ret < 0)
 			return ret;
 	}
@@ -3910,8 +3922,9 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 {
 	u8 genmask = nft_genmask_next(ctx->net);
 	struct nft_set_elem_catchall *catchall;
+
 	struct nft_set_ext *ext;
 	int ret = 0;
 
 	list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
 		ext = nft_set_elem_ext(set, catchall->elem);
@@ -3915,7 +3928,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 
 	list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
 		ext = nft_set_elem_ext(set, catchall->elem);
-		if (!nft_set_elem_active(ext, genmask))
+		if (!nft_set_elem_active(ext, dummy_iter.genmask))
 			continue;
 
 		ret = nft_setelem_validate(ctx, set, NULL, catchall->elem);
@@ -3918,7 +3931,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
-		ret = nft_setelem_validate(ctx, set, NULL, catchall->elem);
+		ret = nft_setelem_validate(ctx, set, &dummy_iter, catchall->elem);
 		if (ret < 0)
 			return ret;
 	}
@@ -5001,6 +5013,11 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 					const struct nft_set_iter *iter,
 					struct nft_set_elem *elem)
 {
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
 	return nft_setelem_data_validate(ctx, set, elem);
 }
 
@@ -5095,6 +5112,13 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 				const struct nft_set_iter *iter,
 				struct nft_set_elem *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))
+		return 0;
+
+	nft_clear(ctx->net, ext);
 	nft_setelem_data_activate(ctx->net, set, elem);
 
 	return 0;
@@ -5113,6 +5137,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
+		nft_clear(ctx->net, ext);
 		elem.priv = catchall->elem;
 		nft_setelem_data_activate(ctx->net, set, &elem);
 		break;
@@ -5407,6 +5420,11 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 					const struct nft_set_iter *iter,
 					struct nft_elem_priv *elem_priv)
 {
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
+
+	if (!nft_set_elem_active(ext, iter->genmask))
+		return 0;
+
 	return nft_setelem_data_validate(ctx, set, elem_priv);
 }
 
@@ -5499,6 +5517,13 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 				const struct nft_set_iter *iter,
 				struct nft_elem_priv *elem_priv)
 {
+	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))
+		return 0;
+
+	nft_clear(ctx->net, ext);
 	nft_setelem_data_activate(ctx->net, set, elem_priv);
 
 	return 0;
@@ -5516,6 +5541,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 		if (!nft_set_elem_active(ext, genmask))
 			continue;
 
+		nft_clear(ctx->net, ext);
 		nft_setelem_data_activate(ctx->net, set, catchall->elem);
 		break;
 	}
@@ -6121,7 +6149,7 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 	struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	if (nft_setelem_is_catchall(set, elem)) {
-		nft_set_elem_change_active(net, set, ext);
+		nft_clear(net, ext);
 	} else {
 		set->ops->activate(net, set, elem);
 	}
@@ -6643,7 +6672,7 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 	struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
 
 	if (nft_setelem_is_catchall(set, elem_priv)) {
-		nft_set_elem_change_active(net, set, ext);
+		nft_clear(net, ext);
 	} else {
 		set->ops->activate(net, set, elem_priv);
 	}
@@ -6793,7 +6793,7 @@
 			     const struct nft_set_iter *iter,
-			     struct nft_elem_priv *elem_priv)
+			     struct nft_set_elem *elem)
 {
-	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
 	struct nft_trans *trans;
 
 	if (!nft_set_elem_active(ext, iter->genmask))
@@ -10066,5 +10066,5 @@
 {
-	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem_priv);
+	const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
 
 	if (!nft_set_elem_active(ext, iter->genmask))
 		return 0;
diff -u b/net/netfilter/nft_set_bitmap.c b/net/netfilter/nft_set_bitmap.c
--- b/net/netfilter/nft_set_bitmap.c
+++ b/net/netfilter/nft_set_bitmap.c
@@ -227,3 +227,3 @@
 
-		iter->err = iter->fn(ctx, set, iter, &be->priv);
+		elem.priv = &be->priv;
 
diff -u b/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c
--- b/net/netfilter/nft_set_hash.c
+++ b/net/netfilter/nft_set_hash.c
@@ -194,5 +194,5 @@
 {
-	struct nft_rhash_elem *he = nft_elem_priv_cast(elem_priv);
+	struct nft_rhash_elem *he = nft_elem_priv_cast(elem->priv);
 
 	nft_clear(net, &he->ext);
 }
@@ -284,5 +284,5 @@
 		if (iter->count < iter->skip)
 			goto cont;
 
-		iter->err = iter->fn(ctx, set, iter, &he->priv);
-		if (iter->err < 0)
+		elem.priv = &he->priv;
+
@@ -608,5 +608,5 @@
 {
-	struct nft_hash_elem *he = nft_elem_priv_cast(elem_priv);
+	struct nft_hash_elem *he = nft_elem_priv_cast(elem->priv);
 
 	nft_clear(net, &he->ext);
 }
@@ -665,5 +665,5 @@
 			if (iter->count < iter->skip)
 				goto cont;
 
-			iter->err = iter->fn(ctx, set, iter, &he->priv);
-			if (iter->err < 0)
+			elem.priv = &he->priv;
+
diff -u b/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
--- b/net/netfilter/nft_set_pipapo.c
+++ b/net/netfilter/nft_set_pipapo.c
@@ -1752,5 +1752,5 @@
 {
-	struct nft_pipapo_elem *e = nft_elem_priv_cast(elem_priv);
+	struct nft_pipapo_elem *e = nft_elem_priv_cast(elem->priv);
 
 	nft_clear(net, &e->ext);
 }
@@ -2049,9 +2049,9 @@
 
 		e = f->mt[r].e;
 
 		if (!nft_set_elem_active(&e->ext, iter->genmask))
 			goto cont;
 
-		iter->err = iter->fn(ctx, set, iter, &e->priv);
-		if (iter->err < 0)
-			goto out;
+		elem.priv = &e->priv;
+
+		iter->err = iter->fn(ctx, set, iter, &elem);
@@ -2052,9 +2052,6 @@ INTERDIFF: rejected hunk from patch1, cannot diff context
 
 		e = f->mt[r].e;
 
-		if (!nft_set_elem_active(&e->ext, iter->genmask))
-			goto cont;
-
 		elem.priv = &e->priv;
 
 		iter->err = iter->fn(ctx, set, iter, &elem);
@@ -2149,9 +2149,6 @@ INTERDIFF: rejected hunk from patch2, cannot diff context
 
 		e = f->mt[r].e;
 
-		if (!nft_set_elem_active(&e->ext, iter->genmask))
-			goto cont;
-
 		iter->err = iter->fn(ctx, set, iter, &e->priv);
 		if (iter->err < 0)
 			goto out;
diff -u b/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
--- b/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -528,5 +528,5 @@
 {
-	struct nft_rbtree_elem *rbe = nft_elem_priv_cast(elem_priv);
+	struct nft_rbtree_elem *rbe = nft_elem_priv_cast(elem->priv);
 
 	nft_clear(net, &rbe->ext);
 }
@@ -597,5 +597,5 @@
 		if (iter->count < iter->skip)
 			goto cont;
 
-		iter->err = iter->fn(ctx, set, iter, &rbe->priv);
-		if (iter->err < 0) {
+		elem.priv = &rbe->priv;
+

This is an automated interdiff check for backported commits.

@github-actions
Copy link

JIRA PR Check Results

3 commit(s) with issues found:

Commit 885832033b5a

Summary: netfilter: nf_tables: restore set elements when delete set fails

❌ Errors:

  • VULN-37622: Status is 'To Do', expected 'In Progress'

⚠️ Warnings:

  • VULN-37622: No time logged - please log time manually

Commit f356abea6745

Summary: netfilter: nf_tables: missing iterator type in lookup walk

⚠️ Warnings:

  • VULN-37652: No time logged - please log time manually

Commit 220ae769a529

Summary: netfilter: nft_set_pipapo: walk over current view on netlink dump

⚠️ Warnings:

  • VULN-37652: No time logged - please log time manually

Summary: Checked 3 commit(s) total.

@github-actions
Copy link

Validation checks completed with issues View full results: https://github.com/ctrliq/kernel-src-tree/actions/runs/20908353549

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants