diff options
| author | Sabrina Dubroca <sd@queasysnail.net> | 2026-02-24 02:05:14 +0300 |
|---|---|---|
| committer | Steffen Klassert <steffen.klassert@secunet.com> | 2026-02-25 11:11:40 +0300 |
| commit | 0c0eef8ccd2413b0a10eb6bbd3442333b1e64dd2 (patch) | |
| tree | 12d1e2fc72d839216bdb200e815617e19e0e6cf7 | |
| parent | 7d2fc41f91bc69acb6e01b0fa23cd7d0109a6a23 (diff) | |
| download | linux-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.c | 9 | ||||
| -rw-r--r-- | net/ipv6/esp6.c | 9 |
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); + } } } |
