]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
psp: validate protocol before mutating skb in psp_dev_encapsulate()
authorJakub Kicinski <kuba@kernel.org>
Tue, 28 Apr 2026 20:53:50 +0000 (13:53 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 29 Apr 2026 23:55:54 +0000 (16:55 -0700)
Code checkers / AI scans will complain that we have already modified
the packet by the time we realize that protocol is not IP.

Move the skb->protocol check to before skb_push()/memmove() so that
the skb is not left in a corrupted state when the function returns
false for an unsupported protocol. psp_dev_rcv() follows similar
pattern.

Today this path is unreachable because both in-tree callers (mlx5 and
netdevsim) only reach psp_dev_encapsulate() from TCP socket TX paths
where skb->protocol is always ETH_P_IP or ETH_P_IPV6, and both drop
the skb on a false return, anyway.

Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260428205352.1247325-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/psp/psp_main.c

index 9508b6c380038b311a9b778933789b5c4cb61007..652ec8a9c8a49cbe871749f22f14cb489830f66a 100644 (file)
@@ -228,6 +228,10 @@ bool psp_dev_encapsulate(struct net *net, struct sk_buff *skb, __be32 spi,
        u32 ethr_len = skb_mac_header_len(skb);
        u32 bufflen = ethr_len + network_len;
 
+       if (skb->protocol != htons(ETH_P_IP) &&
+           skb->protocol != htons(ETH_P_IPV6))
+               return false;
+
        if (skb_cow_head(skb, PSP_ENCAP_HLEN))
                return false;
 
@@ -243,11 +247,9 @@ bool psp_dev_encapsulate(struct net *net, struct sk_buff *skb, __be32 spi,
                ip_hdr(skb)->check = 0;
                ip_hdr(skb)->check =
                        ip_fast_csum((u8 *)ip_hdr(skb), ip_hdr(skb)->ihl);
-       } else if (skb->protocol == htons(ETH_P_IPV6)) {
+       } else {
                ipv6_hdr(skb)->nexthdr = IPPROTO_UDP;
                be16_add_cpu(&ipv6_hdr(skb)->payload_len, PSP_ENCAP_HLEN);
-       } else {
-               return false;
        }
 
        skb_set_inner_ipproto(skb, IPPROTO_TCP);