]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 May 2026 04:23:58 +0000 (06:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 May 2026 04:23:58 +0000 (06:23 +0200)
added patches:
xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch

queue-6.18/series
queue-6.18/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch [new file with mode: 0644]

index daa52157a94c58959ad169f730ee0efa1bf6498e..4c43852c060d13464ec53e2d2e72fb636b6d571a 100644 (file)
@@ -13,3 +13,4 @@ asoc-sof-don-t-allow-pointer-operations-on-unconfigured-streams.patch
 wifi-mt76-mt7925-fix-incorrect-tlv-length-in-clc-command.patch
 spi-rockchip-fix-controller-deregistration.patch
 ksmbd-rewrite-stop_sessions-with-restartable-iteration.patch
+xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch
diff --git a/queue-6.18/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch b/queue-6.18/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch
new file mode 100644 (file)
index 0000000..f3013a5
--- /dev/null
@@ -0,0 +1,96 @@
+From f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4 Mon Sep 17 00:00:00 2001
+From: Kuan-Ting Chen <h3xrabbit@gmail.com>
+Date: Mon, 4 May 2026 23:27:12 +0800
+Subject: xfrm: esp: avoid in-place decrypt on shared skb frags
+
+From: Kuan-Ting Chen <h3xrabbit@gmail.com>
+
+commit f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4 upstream.
+
+MSG_SPLICE_PAGES can attach pages from a pipe directly to an skb. TCP
+marks such skbs with SKBFL_SHARED_FRAG after skb_splice_from_iter(),
+so later paths that may modify packet data can first make a private
+copy. The IPv4/IPv6 datagram append paths did not set this flag when
+splicing pages into UDP skbs.
+
+That leaves an ESP-in-UDP packet made from shared pipe pages looking
+like an ordinary uncloned nonlinear skb. ESP input then takes the no-COW
+fast path for uncloned skbs without a frag_list and decrypts in place
+over data that is not owned privately by the skb.
+
+Mark IPv4/IPv6 datagram splice frags with SKBFL_SHARED_FRAG, matching
+TCP. Also make ESP input fall back to skb_cow_data() when the flag is
+present, so ESP does not decrypt externally backed frags in place.
+Private nonlinear skb frags still use the existing fast path.
+
+This intentionally does not change ESP output. In esp_output_head(),
+the path that appends the ESP trailer to existing skb tailroom without
+calling skb_cow_data() is not reachable for nonlinear skbs:
+skb_tailroom() returns zero when skb->data_len is nonzero, while ESP
+tailen is positive. Thus ESP output will either use the separate
+destination-frag path or fall back to skb_cow_data().
+
+Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
+Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
+Fixes: 7da0dde68486 ("ip, udp: Support MSG_SPLICE_PAGES")
+Fixes: 6d8192bd69bb ("ip6, udp6: Support MSG_SPLICE_PAGES")
+Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
+Reported-by: Kuan-Ting Chen <h3xrabbit@gmail.com>
+Tested-by: Hyunwoo Kim <imv4bel@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Kuan-Ting Chen <h3xrabbit@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/esp4.c       |    3 ++-
+ net/ipv4/ip_output.c  |    2 ++
+ net/ipv6/esp6.c       |    3 ++-
+ net/ipv6/ip6_output.c |    2 ++
+ 4 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -873,7 +873,8 @@ static int esp_input(struct xfrm_state *
+                       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
+@@ -1233,6 +1233,8 @@ alloc_new_skb:
+                       if (err < 0)
+                               goto error;
+                       copy = err;
++                      if (!(flags & MSG_NO_SHARED_FRAGS))
++                              skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
+                       wmem_alloc_delta += copy;
+               } else if (!zc) {
+                       int i = skb_shinfo(skb)->nr_frags;
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -915,7 +915,8 @@ static int esp6_input(struct xfrm_state
+                       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/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1777,6 +1777,8 @@ alloc_new_skb:
+                       if (err < 0)
+                               goto error;
+                       copy = err;
++                      if (!(flags & MSG_NO_SHARED_FRAGS))
++                              skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
+                       wmem_alloc_delta += copy;
+               } else if (!zc) {
+                       int i = skb_shinfo(skb)->nr_frags;