Commit 3bfc7782 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Florian Westphal says:

====================
Netfilter fixes for net

The following patchset contains Netfilter fixes for *net*:

1) I managed to add a null dereference crash in nft_set_pipapo
   in the current development cycle, was not caught by CI
   because the avx2 implementation is fine, but selftest
   splats when run on non-avx2 host.

2) Fix the ipvs estimater kthread affinity, was incorrect
   since 6.14. From Frederic Weisbecker.

3) nf_tables should not allow to add a device to a flowtable
   or netdev chain more than once -- reject this.
   From Pablo Neira Ayuso.  This has been broken for long time,
   blamed commit dates from v5.8.

* tag 'nf-25-08-13' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  netfilter: nf_tables: reject duplicate device on updates
  ipvs: Fix estimator kthreads preferred affinity
  netfilter: nft_set_pipapo: fix null deref for empty set
====================

Link: https://patch.msgid.link/20250813113800.20775-1-fw@strlen.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d7e82594 cf5fb87f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1163,6 +1163,14 @@ static inline const struct cpumask *sysctl_est_cpulist(struct netns_ipvs *ipvs)
		return housekeeping_cpumask(HK_TYPE_KTHREAD);
}

static inline const struct cpumask *sysctl_est_preferred_cpulist(struct netns_ipvs *ipvs)
{
	if (ipvs->est_cpulist_valid)
		return ipvs->sysctl_est_cpulist;
	else
		return NULL;
}

static inline int sysctl_est_nice(struct netns_ipvs *ipvs)
{
	return ipvs->sysctl_est_nice;
@@ -1270,6 +1278,11 @@ static inline const struct cpumask *sysctl_est_cpulist(struct netns_ipvs *ipvs)
	return housekeeping_cpumask(HK_TYPE_KTHREAD);
}

static inline const struct cpumask *sysctl_est_preferred_cpulist(struct netns_ipvs *ipvs)
{
	return NULL;
}

static inline int sysctl_est_nice(struct netns_ipvs *ipvs)
{
	return IPVS_EST_NICE;
+1 −0
Original line number Diff line number Diff line
@@ -893,6 +893,7 @@ int kthread_affine_preferred(struct task_struct *p, const struct cpumask *mask)

	return ret;
}
EXPORT_SYMBOL_GPL(kthread_affine_preferred);

/*
 * Re-affine kthreads according to their preferences
+2 −1
Original line number Diff line number Diff line
@@ -265,7 +265,8 @@ int ip_vs_est_kthread_start(struct netns_ipvs *ipvs,
	}

	set_user_nice(kd->task, sysctl_est_nice(ipvs));
	set_cpus_allowed_ptr(kd->task, sysctl_est_cpulist(ipvs));
	if (sysctl_est_preferred_cpulist(ipvs))
		kthread_affine_preferred(kd->task, sysctl_est_preferred_cpulist(ipvs));

	pr_info("starting estimator thread %d...\n", kd->id);
	wake_up_process(kd->task);
+30 −0
Original line number Diff line number Diff line
@@ -2803,6 +2803,7 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
	struct nft_chain *chain = ctx->chain;
	struct nft_chain_hook hook = {};
	struct nft_stats __percpu *stats = NULL;
	struct nftables_pernet *nft_net;
	struct nft_hook *h, *next;
	struct nf_hook_ops *ops;
	struct nft_trans *trans;
@@ -2845,6 +2846,20 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
				if (nft_hook_list_find(&basechain->hook_list, h)) {
					list_del(&h->list);
					nft_netdev_hook_free(h);
					continue;
				}

				nft_net = nft_pernet(ctx->net);
				list_for_each_entry(trans, &nft_net->commit_list, list) {
					if (trans->msg_type != NFT_MSG_NEWCHAIN ||
					    trans->table != ctx->table ||
					    !nft_trans_chain_update(trans))
						continue;

					if (nft_hook_list_find(&nft_trans_chain_hooks(trans), h)) {
						nft_chain_release_hook(&hook);
						return -EEXIST;
					}
				}
			}
		} else {
@@ -9060,6 +9075,7 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
{
	const struct nlattr * const *nla = ctx->nla;
	struct nft_flowtable_hook flowtable_hook;
	struct nftables_pernet *nft_net;
	struct nft_hook *hook, *next;
	struct nf_hook_ops *ops;
	struct nft_trans *trans;
@@ -9076,6 +9092,20 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
		if (nft_hook_list_find(&flowtable->hook_list, hook)) {
			list_del(&hook->list);
			nft_netdev_hook_free(hook);
			continue;
		}

		nft_net = nft_pernet(ctx->net);
		list_for_each_entry(trans, &nft_net->commit_list, list) {
			if (trans->msg_type != NFT_MSG_NEWFLOWTABLE ||
			    trans->table != ctx->table ||
			    !nft_trans_flowtable_update(trans))
				continue;

			if (nft_hook_list_find(&nft_trans_flowtable_hooks(trans), hook)) {
				err = -EEXIST;
				goto err_flowtable_update_hook;
			}
		}
	}

+2 −3
Original line number Diff line number Diff line
@@ -426,10 +426,9 @@ static struct nft_pipapo_elem *pipapo_get(const struct nft_pipapo_match *m,

	local_bh_disable();

	if (unlikely(!raw_cpu_ptr(m->scratch)))
		goto out;

	scratch = *raw_cpu_ptr(m->scratch);
	if (unlikely(!scratch))
		goto out;

	map_index = scratch->map_index;