kernel/SOURCES/1100-xfrm-esp-avoid-in-place-decrypt-shared-skb-frags.patch
Andrew Lukoshko 1e1b296ebe Bump version to 4.18.0-553.123.2
xfrm: esp: avoid in-place decrypt on shared skb frags
(upstream commit f4c50a4034e6)

Introduce tarfile_release indirection so pkgrelease can advance
independently of the imported source tarball.
2026-05-07 17:28:18 +00:00

76 lines
2.5 KiB
Diff

From: Andrew Lukoshko <alukoshko@almalinux.org>
Subject: [PATCH AlmaLinux 8] xfrm: esp: avoid in-place decrypt on shared skb frags
Backport of upstream commit f4c50a4034e6 ("xfrm: esp: avoid in-place
decrypt on shared skb frags") for AlmaLinux 8 (4.18 kernel).
Verified to apply with `patch -p1 -F0` (no offset, no fuzz, no rejects)
against kernel-4.18.0-553.123.1.el8_10.
ESP-in-UDP packets built from caller-owned pages (e.g. pipe pages
attached via udp_sendpage(2) -> ip_append_page() -> skb_append_pagefrags())
look like ordinary uncloned nonlinear skbs. ESP input then takes the
no-COW fast path and decrypts in place over data that is not owned
privately by the skb, which can be read or modified by an unprivileged
process holding the pages.
Tree adaptation:
* Upstream patches __ip_append_data() / __ip6_append_data(), the
MSG_SPLICE_PAGES branch added by 7da0dde68486 / 6d8192bd69bb.
That feature is not present in the 4.18 tree.
* The age-equivalent producer is ip_append_page() (called from
udp_sendpage). Mark frags there using SKBTX_SHARED_FRAG, which
is what skb_has_shared_frag() already checks on this kernel.
* UDPv6 has no .sendpage op in this tree, so the esp6 hunk is
defense-in-depth in case a later backport adds one.
* The esp4/esp6 receiver-side hunks are taken verbatim from
upstream.
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
(cherry picked from commit f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4)
Signed-off-by: Andrew Lukoshko <alukoshko@almalinux.org>
---
net/ipv4/esp4.c | 3 ++-
net/ipv4/ip_output.c | 2 ++
net/ipv6/esp6.c | 3 ++-
3 files changed, 6 insertions(+), 2 deletions(-)
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -913,7 +913,8 @@
nfrags = 1;
goto skip_cow;
- } else if (!skb_has_frag_list(skb)) {
+ } else if (!skb_has_frag_list(skb) &&
+ !skb_has_shared_frag(skb)) {
nfrags = skb_shinfo(skb)->nr_frags;
nfrags++;
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1346,6 +1346,8 @@
err = -EMSGSIZE;
goto error;
}
+ if (!(flags & MSG_NO_SHARED_FRAGS))
+ skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
if (skb->ip_summed == CHECKSUM_NONE) {
__wsum csum;
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -971,7 +971,8 @@
nfrags = 1;
goto skip_cow;
- } else if (!skb_has_frag_list(skb)) {
+ } else if (!skb_has_frag_list(skb) &&
+ !skb_has_shared_frag(skb)) {
nfrags = skb_shinfo(skb)->nr_frags;
nfrags++;
--
2.43.0