]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfrm: esp: restore combined single-frag length gate
authorJingguo Tan <tanjingguo@huawei.com>
Mon, 18 May 2026 09:06:48 +0000 (17:06 +0800)
committerSteffen Klassert <steffen.klassert@secunet.com>
Fri, 22 May 2026 07:20:26 +0000 (09:20 +0200)
The ESP out-of-place fast path appends the trailer in esp_output_head()
before esp_output_tail() allocates the destination page frag. The
head-side gate currently checks skb->data_len and tailen separately, but
the tail code allocates a single destination frag from the combined
post-trailer skb->data_len.

Reject the page-frag fast path when the combined aligned length exceeds a
page. Otherwise skb_page_frag_refill() may fall back to a single page while
the destination sg still spans the combined skb->data_len.

Restore this combined-length page gate 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 <malin89@huawei.com>
Signed-off-by: Chenyuan Mi <michenyuan@huawei.com>
Signed-off-by: Jingguo Tan <tanjingguo@huawei.com>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/ipv4/esp4.c
net/ipv6/esp6.c

index 8314d7bddcb715e4dfafd48b54c8ecfc9973c764..5d3a8656687e014f6df15fb879c1a89dd2fe15c8 100644 (file)
@@ -419,8 +419,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)
+       if (ALIGN(skb->data_len + tailen, L1_CACHE_BYTES) >
+           PAGE_SIZE)
                goto cow;
 
        if (!skb_cloned(skb)) {
index 9d0c4957ac627631f3c1b9ead0490a173d3941e3..b963b8e72604acd9658c41b417534d6d4cc7b9a9 100644 (file)
@@ -448,8 +448,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)
+       if (ALIGN(skb->data_len + tailen, L1_CACHE_BYTES) >
+           PAGE_SIZE)
                goto cow;
 
        if (!skb_cloned(skb)) {