]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
esp: fix skb leak with espintcp and async crypto
authorSabrina Dubroca <sd@queasysnail.net>
Mon, 23 Feb 2026 23:05:14 +0000 (00:05 +0100)
committerSteffen Klassert <steffen.klassert@secunet.com>
Wed, 25 Feb 2026 08:11:40 +0000 (09:11 +0100)
When the TX queue for espintcp is full, esp_output_tail_tcp will
return an error and not free the skb, because with synchronous crypto,
the common xfrm output code will drop the packet for us.

With async crypto (esp_output_done), we need to drop the skb when
esp_output_tail_tcp returns an error.

Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/ipv4/esp4.c
net/ipv6/esp6.c

index 2c922afadb8f6bdfd1949db47b35c357aee9ad77..6dfc0bcdef65429b03e8fd117a4ad15558d9ca79 100644 (file)
@@ -235,10 +235,13 @@ static void esp_output_done(void *data, int err)
                xfrm_dev_resume(skb);
        } else {
                if (!err &&
-                   x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
-                       esp_output_tail_tcp(x, skb);
-               else
+                   x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP) {
+                       err = esp_output_tail_tcp(x, skb);
+                       if (err != -EINPROGRESS)
+                               kfree_skb(skb);
+               } else {
                        xfrm_output_resume(skb_to_full_sk(skb), skb, err);
+               }
        }
 }
 
index e75da98f528387932d3158558f35ab2a18d34e01..9f75313734f8cd5c9ef419990a4e846cee2d23cf 100644 (file)
@@ -271,10 +271,13 @@ static void esp_output_done(void *data, int err)
                xfrm_dev_resume(skb);
        } else {
                if (!err &&
-                   x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP)
-                       esp_output_tail_tcp(x, skb);
-               else
+                   x->encap && x->encap->encap_type == TCP_ENCAP_ESPINTCP) {
+                       err = esp_output_tail_tcp(x, skb);
+                       if (err != -EINPROGRESS)
+                               kfree_skb(skb);
+               } else {
                        xfrm_output_resume(skb_to_full_sk(skb), skb, err);
+               }
        }
 }