Commit 0240bceb 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:

Patch #1 sets on NFT_PKTINFO_L4PROTO for UDP packets less than 4 bytes
payload from netdev/egress by subtracting skb_network_offset() when
validating IPv4 packet length, otherwise 'meta l4proto udp' never
matches.

Patch #2 subtracts skb_network_offset() when validating IPv6 packet
length for netdev/egress.

netfilter pull request 24-08-28

* tag 'nf-24-08-28' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  netfilter: nf_tables_ipv6: consider network offset in netdev/egress validation
  netfilter: nf_tables: restore IP sanity checks for netdev/egress
====================

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


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 6213dcc7 70c261d5
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt)
static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
{
	struct iphdr *iph, _iph;
	u32 len, thoff;
	u32 len, thoff, skb_len;

	iph = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb),
				 sizeof(*iph), &_iph);
@@ -30,8 +30,10 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
		return -1;

	len = iph_totlen(pkt->skb, iph);
	thoff = skb_network_offset(pkt->skb) + (iph->ihl * 4);
	if (pkt->skb->len < len)
	thoff = iph->ihl * 4;
	skb_len = pkt->skb->len - skb_network_offset(pkt->skb);

	if (skb_len < len)
		return -1;
	else if (len < thoff)
		return -1;
@@ -40,7 +42,7 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)

	pkt->flags = NFT_PKTINFO_L4PROTO;
	pkt->tprot = iph->protocol;
	pkt->thoff = thoff;
	pkt->thoff = skb_network_offset(pkt->skb) + thoff;
	pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET;

	return 0;
+3 −2
Original line number Diff line number Diff line
@@ -31,8 +31,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt)
	struct ipv6hdr *ip6h, _ip6h;
	unsigned int thoff = 0;
	unsigned short frag_off;
	u32 pkt_len, skb_len;
	int protohdr;
	u32 pkt_len;

	ip6h = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb),
				  sizeof(*ip6h), &_ip6h);
@@ -43,7 +43,8 @@ static inline int __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt)
		return -1;

	pkt_len = ntohs(ip6h->payload_len);
	if (pkt_len + sizeof(*ip6h) > pkt->skb->len)
	skb_len = pkt->skb->len - skb_network_offset(pkt->skb);
	if (pkt_len + sizeof(*ip6h) > skb_len)
		return -1;

	protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);