summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSabrina Dubroca <sd@queasysnail.net>2026-02-24 02:05:14 +0300
committerSteffen Klassert <steffen.klassert@secunet.com>2026-02-25 11:11:40 +0300
commit0c0eef8ccd2413b0a10eb6bbd3442333b1e64dd2 (patch)
tree12d1e2fc72d839216bdb200e815617e19e0e6cf7
parent7d2fc41f91bc69acb6e01b0fa23cd7d0109a6a23 (diff)
downloadlinux-0c0eef8ccd2413b0a10eb6bbd3442333b1e64dd2.tar.xz
esp: fix skb leak with espintcp and async crypto
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>
-rw-r--r--net/ipv4/esp4.c9
-rw-r--r--net/ipv6/esp6.c9
2 files changed, 12 insertions, 6 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 2c922afadb8f..6dfc0bcdef65 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -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);
+ }
}
}
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index e75da98f5283..9f75313734f8 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -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);
+ }
}
}