mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
netfilter: nf_tables: restore IP sanity checks for netdev/egress
[ Upstream commit 5fd0628918977a0afdc2e6bc562d8751b5d3b8c5 ]
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: 0ae8e4cca787 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
3723a05fdb
commit
a369766dd3
@@ -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)
|
static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
|
||||||
{
|
{
|
||||||
struct iphdr *iph, _iph;
|
struct iphdr *iph, _iph;
|
||||||
u32 len, thoff;
|
u32 len, thoff, skb_len;
|
||||||
|
|
||||||
iph = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb),
|
iph = skb_header_pointer(pkt->skb, skb_network_offset(pkt->skb),
|
||||||
sizeof(*iph), &_iph);
|
sizeof(*iph), &_iph);
|
||||||
@@ -30,15 +30,17 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
len = iph_totlen(pkt->skb, iph);
|
len = iph_totlen(pkt->skb, iph);
|
||||||
thoff = skb_network_offset(pkt->skb) + (iph->ihl * 4);
|
thoff = iph->ihl * 4;
|
||||||
if (pkt->skb->len < len)
|
skb_len = pkt->skb->len - skb_network_offset(pkt->skb);
|
||||||
|
|
||||||
|
if (skb_len < len)
|
||||||
return -1;
|
return -1;
|
||||||
else if (len < thoff)
|
else if (len < thoff)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pkt->flags = NFT_PKTINFO_L4PROTO;
|
pkt->flags = NFT_PKTINFO_L4PROTO;
|
||||||
pkt->tprot = iph->protocol;
|
pkt->tprot = iph->protocol;
|
||||||
pkt->thoff = thoff;
|
pkt->thoff = skb_network_offset(pkt->skb) + thoff;
|
||||||
pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET;
|
pkt->fragoff = ntohs(iph->frag_off) & IP_OFFSET;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user