Skip to content

Commit

Permalink
netfilter: nf_tables: restore IP sanity checks for netdev/egress
Browse files Browse the repository at this point in the history
[ Upstream commit 5fd0628 ]

Subtract network offset to skb->len before performing IPv4 header sanity
checks, then adjust transport offset from offset from mac header.

Jorge Ortiz says:

When small UDP packets (< 4 bytes payload) are sent from eth0,
`meta l4proto udp` condition is not met because `NFT_PKTINFO_L4PROTO` is
not set. This happens because there is a comparison that checks if the
transport header offset exceeds the total length.  This comparison does
not take into account the fact that the skb network offset might be
non-zero in egress mode (e.g., 14 bytes for Ethernet header).

Fixes: 0ae8e4c ("netfilter: nf_tables: set transport offset from mac header for netdev/egress")
Reported-by: Jorge Ortiz <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
ummakynes authored and gregkh committed Sep 4, 2024
1 parent fc94b79 commit ac746de
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions include/net/netfilter/nf_tables_ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit ac746de

Please sign in to comment.