From 1e6d45378b272fe2f1fce48ed89d6eaa415c00c2 Mon Sep 17 00:00:00 2001 From: Jingguo Tan Date: Mon, 18 May 2026 17:06:48 +0800 Subject: [PATCH net] xfrm: esp: restore combined single-frag length gate The ESP out-of-place fast path still consumes the combined post-trailer skb->data_len as a single destination frag in esp_output_tail()/ esp6_output_tail(). The head-side gate must therefore reject any case where ALIGN(skb->data_len + tailen, L1_CACHE_BYTES) exceeds PAGE_SIZE, otherwise skb_page_frag_refill() may fall back to a single page and the destination sg will overrun it. Restore a combined-length page gate before entering the page-frag fast path for both IPv4 and IPv6. Fixes: 5bd8baab087d ("esp: limit skb_page_frag_refill use to a single page") Cc: stable@vger.kernel.org Signed-off-by: Lin Ma Signed-off-by: Chenyuan Mi Signed-off-by: Jingguo Tan --- net/ipv4/esp4.c | 5 +++-- net/ipv6/esp6.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 6a5febbdbee49..2d7daca8516c2 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -410,6 +410,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * struct page *page; struct sk_buff *trailer; int tailen = esp->tailen; + unsigned int allocsize; /* this is non-NULL only with TCP/UDP Encapsulation */ if (x->encap) { @@ -419,8 +420,8 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * return err; } - if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE || - ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE) + allocsize = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES); + if (allocsize > PAGE_SIZE) goto cow; if (!skb_cloned(skb)) { diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 9c06c5a1419dc..0fad1dc558b84 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -440,6 +440,7 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info struct page *page; struct sk_buff *trailer; int tailen = esp->tailen; + unsigned int allocsize; if (x->encap) { int err = esp6_output_encap(x, skb, esp); @@ -448,8 +449,8 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info return err; } - if (ALIGN(tailen, L1_CACHE_BYTES) > PAGE_SIZE || - ALIGN(skb->data_len, L1_CACHE_BYTES) > PAGE_SIZE) + allocsize = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES); + if (allocsize > PAGE_SIZE) goto cow; if (!skb_cloned(skb)) { -- 2.43.0