]> git.hungrycats.org Git - linux/commitdiff
xfrm: drop ESP-in-TCP packets with no ingress device
authorZhiling Zou <roxy520tt@gmail.com>
Sat, 18 Jul 2026 07:12:50 +0000 (15:12 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 2 Sep 2026 12:31:49 +0000 (14:31 +0200)
commit e1d7c5ac1c246ce5775f604515de0a59fbf2116e upstream.

ESP-in-TCP receives records through the TCP strparser. handle_esp()
restores skb->dev from the saved skb_iif before passing the packet into
the XFRM input path.

Queued TCP data can be processed after the original ingress device has
been removed, for example during veth or net namespace teardown. In that
case dev_get_by_index_rcu() returns NULL. The XFRM IPv4 and IPv6 input
paths both expect skb->dev to be valid while building the route lookup,
so queued ESP-in-TCP data can dereference a NULL device.

Drop the packet if the saved ingress device can no longer be resolved.
Such a packet can no longer be routed through the normal XFRM receive
path, and this preserves the existing behaviour for packets whose ingress
device still exists.

Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <roxy520tt@gmail.com>
Assisted-by: Codex:gpt-5.4
Reviewed-by: Ren Wei <enjou1224z@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/xfrm/espintcp.c

index 84e9412066b3b1c14a9d903be003a152199c530d..fb47c2f73104017f431de4ebad3442b39baee88b 100644 (file)
@@ -40,6 +40,11 @@ static void handle_esp(struct sk_buff *skb, struct sock *sk)
 
        rcu_read_lock();
        skb->dev = dev_get_by_index_rcu(sock_net(sk), skb->skb_iif);
+       if (!skb->dev) {
+               XFRM_INC_STATS(sock_net(sk), LINUX_MIB_XFRMINERROR);
+               kfree_skb(skb);
+               goto out;
+       }
        local_bh_disable();
 #if IS_ENABLED(CONFIG_IPV6)
        if (sk->sk_family == AF_INET6)
@@ -48,6 +53,7 @@ static void handle_esp(struct sk_buff *skb, struct sock *sk)
 #endif
                xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, TCP_ENCAP_ESPINTCP);
        local_bh_enable();
+out:
        rcu_read_unlock();
 }