From: Greg Kroah-Hartman Date: Fri, 8 May 2026 06:29:15 +0000 (+0200) Subject: add the xfrm patch again. X-Git-Tag: v6.6.138~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5320f542f87bc0afa707b025de1f3fc6b5209cbd;p=thirdparty%2Fkernel%2Fstable-queue.git add the xfrm patch again. --- diff --git a/queue-6.12/series b/queue-6.12/series new file mode 100644 index 0000000000..5af246ea7f --- /dev/null +++ b/queue-6.12/series @@ -0,0 +1 @@ +xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch diff --git a/queue-6.12/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch b/queue-6.12/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch new file mode 100644 index 0000000000..b6cc8dad91 --- /dev/null +++ b/queue-6.12/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch @@ -0,0 +1,96 @@ +From f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4 Mon Sep 17 00:00:00 2001 +From: Kuan-Ting Chen +Date: Mon, 4 May 2026 23:27:12 +0800 +Subject: xfrm: esp: avoid in-place decrypt on shared skb frags + +From: Kuan-Ting Chen + +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 +Reported-by: Kuan-Ting Chen +Tested-by: Hyunwoo Kim +Cc: stable@vger.kernel.org +Signed-off-by: Kuan-Ting Chen +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -872,7 +872,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 +@@ -1231,6 +1231,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 +@@ -914,7 +914,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 +@@ -1761,6 +1761,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; diff --git a/queue-6.18/series b/queue-6.18/series new file mode 100644 index 0000000000..5af246ea7f --- /dev/null +++ b/queue-6.18/series @@ -0,0 +1 @@ +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 index 0000000000..f3013a5e69 --- /dev/null +++ b/queue-6.18/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch @@ -0,0 +1,96 @@ +From f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4 Mon Sep 17 00:00:00 2001 +From: Kuan-Ting Chen +Date: Mon, 4 May 2026 23:27:12 +0800 +Subject: xfrm: esp: avoid in-place decrypt on shared skb frags + +From: Kuan-Ting Chen + +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 +Reported-by: Kuan-Ting Chen +Tested-by: Hyunwoo Kim +Cc: stable@vger.kernel.org +Signed-off-by: Kuan-Ting Chen +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-6.6/series b/queue-6.6/series new file mode 100644 index 0000000000..5af246ea7f --- /dev/null +++ b/queue-6.6/series @@ -0,0 +1 @@ +xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch diff --git a/queue-6.6/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch b/queue-6.6/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch new file mode 100644 index 0000000000..de6274d028 --- /dev/null +++ b/queue-6.6/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch @@ -0,0 +1,96 @@ +From f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4 Mon Sep 17 00:00:00 2001 +From: Kuan-Ting Chen +Date: Mon, 4 May 2026 23:27:12 +0800 +Subject: xfrm: esp: avoid in-place decrypt on shared skb frags + +From: Kuan-Ting Chen + +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 +Reported-by: Kuan-Ting Chen +Tested-by: Hyunwoo Kim +Cc: stable@vger.kernel.org +Signed-off-by: Kuan-Ting Chen +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -1230,6 +1230,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 +@@ -921,7 +921,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 +@@ -1829,6 +1829,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; diff --git a/queue-7.0/series b/queue-7.0/series new file mode 100644 index 0000000000..5af246ea7f --- /dev/null +++ b/queue-7.0/series @@ -0,0 +1 @@ +xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch diff --git a/queue-7.0/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch b/queue-7.0/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch new file mode 100644 index 0000000000..534e121b5d --- /dev/null +++ b/queue-7.0/xfrm-esp-avoid-in-place-decrypt-on-shared-skb-frags.patch @@ -0,0 +1,96 @@ +From f4c50a4034e62ab75f1d5cdd191dd5f9c77fdff4 Mon Sep 17 00:00:00 2001 +From: Kuan-Ting Chen +Date: Mon, 4 May 2026 23:27:12 +0800 +Subject: xfrm: esp: avoid in-place decrypt on shared skb frags + +From: Kuan-Ting Chen + +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 +Reported-by: Kuan-Ting Chen +Tested-by: Hyunwoo Kim +Cc: stable@vger.kernel.org +Signed-off-by: Kuan-Ting Chen +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + 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 +@@ -1765,6 +1765,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;