Commit 53664d51 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Pablo Neira Ayuso says:

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

1) Use get_random_u32() instead of prandom_u32_state() in nft_meta
   and nft_numgen, from Florian Westphal.

2) Incorrect list head in nfnetlink_cttimeout in recent update coming
   from previous development cycle. Also from Florian.

3) Incorrect path to pktgen scripts for nft_concat_range.sh selftest.
   From Jie2x Zhou.

4) Two fixes for the for nft_fwd and nft_dup egress support, from Florian.

* git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  netfilter: nf_dup_netdev: add and use recursion counter
  netfilter: nf_dup_netdev: do not push mac header a second time
  selftests: netfilter: correct PKTGEN_SCRIPT_PATHS in nft_concat_range.sh
  netfilter: cttimeout: fix slab-out-of-bounds read typo in cttimeout_net_exit
  netfilter: use get_random_u32 instead of prandom
====================

Link: https://lore.kernel.org/r/20220621085618.3975-1-pablo@netfilter.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 2642cc6c fcd53c51
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -13,14 +13,31 @@
#include <net/netfilter/nf_tables_offload.h>
#include <net/netfilter/nf_dup_netdev.h>

static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev)
#define NF_RECURSION_LIMIT	2

static DEFINE_PER_CPU(u8, nf_dup_skb_recursion);

static void nf_do_netdev_egress(struct sk_buff *skb, struct net_device *dev,
				enum nf_dev_hooks hook)
{
	if (skb_mac_header_was_set(skb))
	if (__this_cpu_read(nf_dup_skb_recursion) > NF_RECURSION_LIMIT)
		goto err;

	if (hook == NF_NETDEV_INGRESS && skb_mac_header_was_set(skb)) {
		if (skb_cow_head(skb, skb->mac_len))
			goto err;

		skb_push(skb, skb->mac_len);
	}

	skb->dev = dev;
	skb_clear_tstamp(skb);
	__this_cpu_inc(nf_dup_skb_recursion);
	dev_queue_xmit(skb);
	__this_cpu_dec(nf_dup_skb_recursion);
	return;
err:
	kfree_skb(skb);
}

void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif)
@@ -33,7 +50,7 @@ void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif)
		return;
	}

	nf_do_netdev_egress(pkt->skb, dev);
	nf_do_netdev_egress(pkt->skb, dev, nft_hook(pkt));
}
EXPORT_SYMBOL_GPL(nf_fwd_netdev_egress);

@@ -48,7 +65,7 @@ void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif)

	skb = skb_clone(pkt->skb, GFP_ATOMIC);
	if (skb)
		nf_do_netdev_egress(skb, dev);
		nf_do_netdev_egress(skb, dev, nft_hook(pkt));
}
EXPORT_SYMBOL_GPL(nf_dup_netdev_egress);

+1 −1
Original line number Diff line number Diff line
@@ -614,7 +614,7 @@ static void __net_exit cttimeout_net_exit(struct net *net)

	nf_ct_untimeout(net, NULL);

	list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_freelist, head) {
	list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_freelist, free_head) {
		list_del(&cur->free_head);

		if (refcount_dec_and_test(&cur->refcnt))
+2 −11
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/random.h>
#include <linux/smp.h>
#include <linux/static_key.h>
#include <net/dst.h>
@@ -32,8 +33,6 @@
#define NFT_META_SECS_PER_DAY		86400
#define NFT_META_DAYS_PER_WEEK		7

static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);

static u8 nft_meta_weekday(void)
{
	time64_t secs = ktime_get_real_seconds();
@@ -271,13 +270,6 @@ static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest,
	return true;
}

static noinline u32 nft_prandom_u32(void)
{
	struct rnd_state *state = this_cpu_ptr(&nft_prandom_state);

	return prandom_u32_state(state);
}

#ifdef CONFIG_IP_ROUTE_CLASSID
static noinline bool
nft_meta_get_eval_rtclassid(const struct sk_buff *skb, u32 *dest)
@@ -389,7 +381,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
		break;
#endif
	case NFT_META_PRANDOM:
		*dest = nft_prandom_u32();
		*dest = get_random_u32();
		break;
#ifdef CONFIG_XFRM
	case NFT_META_SECPATH:
@@ -518,7 +510,6 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
		len = IFNAMSIZ;
		break;
	case NFT_META_PRANDOM:
		prandom_init_once(&nft_prandom_state);
		len = sizeof(u32);
		break;
#ifdef CONFIG_XFRM
+3 −9
Original line number Diff line number Diff line
@@ -9,12 +9,11 @@
#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/random.h>
#include <linux/static_key.h>
#include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_core.h>

static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);

struct nft_ng_inc {
	u8			dreg;
	u32			modulus;
@@ -135,12 +134,9 @@ struct nft_ng_random {
	u32			offset;
};

static u32 nft_ng_random_gen(struct nft_ng_random *priv)
static u32 nft_ng_random_gen(const struct nft_ng_random *priv)
{
	struct rnd_state *state = this_cpu_ptr(&nft_numgen_prandom_state);

	return reciprocal_scale(prandom_u32_state(state), priv->modulus) +
	       priv->offset;
	return reciprocal_scale(get_random_u32(), priv->modulus) + priv->offset;
}

static void nft_ng_random_eval(const struct nft_expr *expr,
@@ -168,8 +164,6 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,
	if (priv->offset + priv->modulus - 1 < priv->offset)
		return -EOVERFLOW;

	prandom_init_once(&nft_numgen_prandom_state);

	return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg,
					NULL, NFT_DATA_VALUE, sizeof(u32));
}
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ BUGS="flush_remove_add reload"

# List of possible paths to pktgen script from kernel tree for performance tests
PKTGEN_SCRIPT_PATHS="
	../../../samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh
	../../../../samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh
	pktgen/pktgen_bench_xmit_mode_netif_receive.sh"

# Definition of set types: