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.
76 lines
2.5 KiB
Diff
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
|