Commit 9a3cd877 authored by Paolo Abeni's avatar Paolo Abeni
Browse files
Pablo Neira Ayuso says:

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

The following patchset contains Netfilter fixes for net:

1) Restrict xtables extensions to families that are safe, syzbot found
   a way to combine ebtables with extensions that are never used by
   userspace tools. From Florian Westphal.

2) Set l3mdev inconditionally whenever possible in nft_fib to fix lookup
   mismatch, also from Florian.

netfilter pull request 24-10-09

* tag 'nf-24-10-09' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  selftests: netfilter: conntrack_vrf.sh: add fib test case
  netfilter: fib: check correct rtable in vrf setups
  netfilter: xtables: avoid NFPROTO_UNSPEC where needed
====================

Link: https://patch.msgid.link/20241009213858.3565808-1-pablo@netfilter.org


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents ac888d58 c6a0862b
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
		.flowi4_scope = RT_SCOPE_UNIVERSE,
		.flowi4_iif = LOOPBACK_IFINDEX,
		.flowi4_uid = sock_net_uid(nft_net(pkt), NULL),
		.flowi4_l3mdev = l3mdev_master_ifindex_rcu(nft_in(pkt)),
	};
	const struct net_device *oif;
	const struct net_device *found;
@@ -83,9 +84,6 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
	else
		oif = NULL;

	if (priv->flags & NFTA_FIB_F_IIF)
		fl4.flowi4_l3mdev = l3mdev_master_ifindex_rcu(oif);

	if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
	    nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
		nft_fib_store_result(dest, priv, nft_in(pkt));
+3 −2
Original line number Diff line number Diff line
@@ -41,8 +41,6 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,
	if (ipv6_addr_type(&fl6->daddr) & IPV6_ADDR_LINKLOCAL) {
		lookup_flags |= RT6_LOOKUP_F_IFACE;
		fl6->flowi6_oif = get_ifindex(dev ? dev : pkt->skb->dev);
	} else if (priv->flags & NFTA_FIB_F_IIF) {
		fl6->flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev);
	}

	if (ipv6_addr_type(&fl6->saddr) & IPV6_ADDR_UNICAST)
@@ -75,6 +73,8 @@ static u32 __nft_fib6_eval_type(const struct nft_fib *priv,
	else if (priv->flags & NFTA_FIB_F_OIF)
		dev = nft_out(pkt);

	fl6.flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev);

	nft_fib6_flowi_init(&fl6, priv, pkt, dev, iph);

	if (dev && nf_ipv6_chk_addr(nft_net(pkt), &fl6.daddr, dev, true))
@@ -165,6 +165,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
		.flowi6_iif = LOOPBACK_IFINDEX,
		.flowi6_proto = pkt->tprot,
		.flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
		.flowi6_l3mdev = l3mdev_master_ifindex_rcu(nft_in(pkt)),
	};
	struct rt6_info *rt;
	int lookup_flags;
+23 −10
Original line number Diff line number Diff line
@@ -63,24 +63,37 @@ static int checksum_tg_check(const struct xt_tgchk_param *par)
	return 0;
}

static struct xt_target checksum_tg_reg __read_mostly = {
static struct xt_target checksum_tg_reg[] __read_mostly = {
	{
		.name		= "CHECKSUM",
		.family		= NFPROTO_IPV4,
		.target		= checksum_tg,
		.targetsize	= sizeof(struct xt_CHECKSUM_info),
		.table		= "mangle",
		.checkentry	= checksum_tg_check,
		.me		= THIS_MODULE,
	},
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
	{
		.name		= "CHECKSUM",
	.family		= NFPROTO_UNSPEC,
		.family		= NFPROTO_IPV6,
		.target		= checksum_tg,
		.targetsize	= sizeof(struct xt_CHECKSUM_info),
		.table		= "mangle",
		.checkentry	= checksum_tg_check,
		.me		= THIS_MODULE,
	},
#endif
};

static int __init checksum_tg_init(void)
{
	return xt_register_target(&checksum_tg_reg);
	return xt_register_targets(checksum_tg_reg, ARRAY_SIZE(checksum_tg_reg));
}

static void __exit checksum_tg_exit(void)
{
	xt_unregister_target(&checksum_tg_reg);
	xt_unregister_targets(checksum_tg_reg, ARRAY_SIZE(checksum_tg_reg));
}

module_init(checksum_tg_init);
+14 −2
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ static struct xt_target classify_tg_reg[] __read_mostly = {
	{
		.name       = "CLASSIFY",
		.revision   = 0,
		.family     = NFPROTO_UNSPEC,
		.family     = NFPROTO_IPV4,
		.hooks      = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
			      (1 << NF_INET_POST_ROUTING),
		.target     = classify_tg,
@@ -54,6 +54,18 @@ static struct xt_target classify_tg_reg[] __read_mostly = {
		.targetsize = sizeof(struct xt_classify_target_info),
		.me         = THIS_MODULE,
	},
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
	{
		.name       = "CLASSIFY",
		.revision   = 0,
		.family     = NFPROTO_IPV6,
		.hooks      = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
			      (1 << NF_INET_POST_ROUTING),
		.target     = classify_tg,
		.targetsize = sizeof(struct xt_classify_target_info),
		.me         = THIS_MODULE,
	},
#endif
};

static int __init classify_tg_init(void)
+25 −11
Original line number Diff line number Diff line
@@ -114,25 +114,39 @@ static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
	nf_ct_netns_put(par->net, par->family);
}

static struct xt_target connsecmark_tg_reg __read_mostly = {
static struct xt_target connsecmark_tg_reg[] __read_mostly = {
	{
		.name       = "CONNSECMARK",
		.revision   = 0,
		.family     = NFPROTO_IPV4,
		.checkentry = connsecmark_tg_check,
		.destroy    = connsecmark_tg_destroy,
		.target     = connsecmark_tg,
		.targetsize = sizeof(struct xt_connsecmark_target_info),
		.me         = THIS_MODULE,
	},
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
	{
		.name       = "CONNSECMARK",
		.revision   = 0,
	.family     = NFPROTO_UNSPEC,
		.family     = NFPROTO_IPV6,
		.checkentry = connsecmark_tg_check,
		.destroy    = connsecmark_tg_destroy,
		.target     = connsecmark_tg,
		.targetsize = sizeof(struct xt_connsecmark_target_info),
		.me         = THIS_MODULE,
	},
#endif
};

static int __init connsecmark_tg_init(void)
{
	return xt_register_target(&connsecmark_tg_reg);
	return xt_register_targets(connsecmark_tg_reg, ARRAY_SIZE(connsecmark_tg_reg));
}

static void __exit connsecmark_tg_exit(void)
{
	xt_unregister_target(&connsecmark_tg_reg);
	xt_unregister_targets(connsecmark_tg_reg, ARRAY_SIZE(connsecmark_tg_reg));
}

module_init(connsecmark_tg_init);
Loading