]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: use skb_ip_totlen and iph_totlen
authorXin Long <lucien.xin@gmail.com>
Sat, 28 Jan 2023 15:58:34 +0000 (10:58 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Jan 2024 16:10:21 +0000 (17:10 +0100)
[ Upstream commit a13fbf5ed5b4fc9095f12e955ca3a59b5507ff01 ]

There are also quite some places in netfilter that may process IPv4 TCP
GSO packets, we need to replace them too.

In length_mt(), we have to use u_int32_t/int to accept skb_ip_totlen()
return value, otherwise it may overflow and mismatch. This change will
also help us add selftest for IPv4 BIG TCP in the following patch.

Note that we don't need to replace the one in tcpmss_tg4(), as it will
return if there is data after tcphdr in tcpmss_mangle_packet(). The
same in mangle_contents() in nf_nat_helper.c, it returns false when
skb->len + extra > 65535 in enlarge_skb().

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 0ae8e4cca787 ("netfilter: nf_tables: set transport offset from mac header for netdev/egress")
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/net/netfilter/nf_tables_ipv4.h
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/nf_log_syslog.c
net/netfilter/xt_length.c

index c4a6147b0ef8ce4dcdb1ce0f0b61e3636c5142e4..d8f6cb47ebe379d6350d45588312345cecaa7ffc 100644 (file)
@@ -29,7 +29,7 @@ static inline int __nft_set_pktinfo_ipv4_validate(struct nft_pktinfo *pkt)
        if (iph->ihl < 5 || iph->version != 4)
                return -1;
 
-       len = ntohs(iph->tot_len);
+       len = iph_totlen(pkt->skb, iph);
        thoff = iph->ihl * 4;
        if (pkt->skb->len < len)
                return -1;
@@ -62,7 +62,7 @@ static inline int nft_set_pktinfo_ipv4_ingress(struct nft_pktinfo *pkt)
        if (iph->ihl < 5 || iph->version != 4)
                goto inhdr_error;
 
-       len = ntohs(iph->tot_len);
+       len = iph_totlen(pkt->skb, iph);
        thoff = iph->ihl * 4;
        if (pkt->skb->len < len) {
                __IP_INC_STATS(nft_net(pkt), IPSTATS_MIB_INTRUNCATEDPKTS);
index 7243079ef354649a085f2c261095f37f68ba6004..b452eb3ddcecbb61b4cb63bc5f9eebac23fe6945 100644 (file)
@@ -994,7 +994,7 @@ ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af,
                old_dsfield = ipv4_get_dsfield(old_iph);
                *ttl = old_iph->ttl;
                if (payload_len)
-                       *payload_len = ntohs(old_iph->tot_len);
+                       *payload_len = skb_ip_totlen(skb);
        }
 
        /* Implement full-functionality option for ECN encapsulation */
index cb894f0d63e9d300a47bfc1c723a0a79c8913c75..c66689ad2b491977876aa47e6d4201de29244950 100644 (file)
@@ -322,7 +322,7 @@ dump_ipv4_packet(struct net *net, struct nf_log_buf *m,
 
        /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
        nf_log_buf_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
-                      ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
+                      iph_totlen(skb, ih), ih->tos & IPTOS_TOS_MASK,
                       ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
 
        /* Max length: 6 "CE DF MF " */
index 9fbfad13176f080c34bcde72bc10c7db238c240b..ca730cedb5d41d28634d197ef90499866fb194d6 100644 (file)
@@ -21,7 +21,7 @@ static bool
 length_mt(const struct sk_buff *skb, struct xt_action_param *par)
 {
        const struct xt_length_info *info = par->matchinfo;
-       u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
+       u32 pktlen = skb_ip_totlen(skb);
 
        return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
 }