Skip to content

Commit 5fd0628

Browse files
committed
netfilter: nf_tables: restore IP sanity checks for netdev/egress
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 <jorge.ortiz.escribano@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
1 parent 8af174e commit 5fd0628

1 file changed

Lines changed: 6 additions & 4 deletions

File tree

include/net/netfilter/nf_tables_ipv4.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt)
1919
static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
2020
{
2121
struct iphdr *iph, _iph;
22-
u32 len, thoff;
22+
u32 len, thoff, skb_len;
2323

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

3232
len = iph_totlen(pkt->skb, iph);
33-
thoff = skb_network_offset(pkt->skb) + (iph->ihl * 4);
34-
if (pkt->skb->len < len)
33+
thoff = iph->ihl * 4;
34+
skb_len = pkt->skb->len - skb_network_offset(pkt->skb);
35+
36+
if (skb_len < len)
3537
return -1;
3638
else if (len < thoff)
3739
return -1;
@@ -40,7 +42,7 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
4042

4143
pkt->flags = NFT_PKTINFO_L4PROTO;
4244
pkt->tprot = iph->protocol;
43-
pkt->thoff = thoff;
45+
pkt->thoff = skb_network_offset(pkt->skb) + thoff;
4446
pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET;
4547

4648
return 0;

0 commit comments

Comments
 (0)