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

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

The following patchset contains two Netfilter fixes for net:

Patch #1 fixes CONFIG_SYSCTL=n for a patch coming in the previous PR
	 to move the sysctl toggle to enable SRv6 netfilter hooks from
	 nf_conntrack to the core, from Jianguo Wu.

Patch #2 fixes a possible pointer leak to userspace due to insufficient
	 validation of NFT_DATA_VALUE.

Linus found this pointer leak to userspace via zdi-disclosures@ and
forwarded the notice to Netfilter maintainers, he appears as reporter
because whoever found this issue never approached Netfilter
maintainers neither via security@ nor in private.

netfilter pull request 24-06-27

* tag 'nf-24-06-27' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data registers
  netfilter: fix undefined reference to 'netfilter_lwtunnel_*' when CONFIG_SYSCTL=n
====================

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


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 1864b822 7931d329
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -619,6 +619,11 @@ static inline void *nft_set_priv(const struct nft_set *set)
	return (void *)set->data;
}

static inline enum nft_data_types nft_set_datatype(const struct nft_set *set)
{
	return set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE;
}

static inline bool nft_set_gc_is_pending(const struct nft_set *s)
{
	return refcount_read(&s->refs) != 1;
+3 −0
Original line number Diff line number Diff line
@@ -117,4 +117,7 @@ void netfilter_lwtunnel_fini(void)
{
	unregister_pernet_subsys(&nf_lwtunnel_net_ops);
}
#else
int __init netfilter_lwtunnel_init(void) { return 0; }
void netfilter_lwtunnel_fini(void) {}
#endif /* CONFIG_SYSCTL */
+4 −4
Original line number Diff line number Diff line
@@ -5740,8 +5740,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,

	if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
	    nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext),
			  set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
			  set->dlen) < 0)
			  nft_set_datatype(set), set->dlen) < 0)
		goto nla_put_failure;

	if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPRESSIONS) &&
@@ -11073,6 +11072,9 @@ static int nft_validate_register_store(const struct nft_ctx *ctx,

		return 0;
	default:
		if (type != NFT_DATA_VALUE)
			return -EINVAL;

		if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
			return -EINVAL;
		if (len == 0)
@@ -11081,8 +11083,6 @@ static int nft_validate_register_store(const struct nft_ctx *ctx,
		    sizeof_field(struct nft_regs, data))
			return -ERANGE;

		if (data != NULL && type != NFT_DATA_VALUE)
			return -EINVAL;
		return 0;
	}
}
+2 −1
Original line number Diff line number Diff line
@@ -132,7 +132,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
			return -EINVAL;

		err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG],
					       &priv->dreg, NULL, set->dtype,
					       &priv->dreg, NULL,
					       nft_set_datatype(set),
					       set->dlen);
		if (err < 0)
			return err;