All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hyunwoo Kim <imv4bel@gmail.com>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org, kerneljasonxing@gmail.com,
	kuniyu@google.com, mhal@rbox.co, jiayuan.chen@linux.dev,
	steffen.klassert@secunet.com, ben@decadent.org.uk,
	herbert@gondor.apana.org.au, dsahern@kernel.org,
	sultan@kerneltoast.com, sd@queasysnail.net, malin89@huawei.com,
	tanjingguo@huawei.com
Cc: netdev@vger.kernel.org, stable@vger.kernel.org, imv4bel@gmail.com
Subject: Re: [PATCH net v4] net: skbuff: propagate shared-frag marker through frag-transfer helpers
Date: Fri, 15 May 2026 15:07:37 +0900	[thread overview]
Message-ID: <aga4KZtvaRQAMv6B@v4bel> (raw)
In-Reply-To: <aga1VyHpHaUhnGZa@v4bel>

On Fri, May 15, 2026 at 02:55:35PM +0900, Hyunwoo Kim wrote:
> Two frag-transfer helpers (__pskb_copy_fclone() and skb_shift()) fail
> to propagate the SKBFL_SHARED_FRAG bit in skb_shinfo()->flags when
> moving frags from source to destination.  __pskb_copy_fclone() defers
> the rest of the shinfo metadata to skb_copy_header() after copying
> frag descriptors, but that helper only carries over gso_{size,segs,
> type} and never touches skb_shinfo()->flags; skb_shift() moves frag
> descriptors directly and leaves flags untouched.  As a result, the
> destination skb keeps a reference to the same externally-owned or
> page-cache-backed pages while reporting skb_has_shared_frag() as
> false.
> 
> The mismatch is harmful in any in-place writer that uses
> skb_has_shared_frag() to decide whether shared pages must be detoured
> through skb_cow_data().  ESP input is one such writer (esp4.c,
> esp6.c), and a single nft 'dup to <local>' rule -- or any other
> nf_dup_ipv4() / xt_TEE caller -- is enough to land a pskb_copy()'d
> skb in esp_input() with the marker stripped, letting an unprivileged
> user write into the page cache of a root-owned read-only file via
> authencesn-ESN stray writes.
> 
> Set SKBFL_SHARED_FRAG on the destination whenever frag descriptors
> were actually moved from the source.  skb_copy() and skb_copy_expand()
> share skb_copy_header() too but linearize all paged data into freshly
> allocated head storage and emerge with nr_frags == 0, so
> skb_has_shared_frag() returns false on its own; they need no change.
> 
> The same omission exists in skb_gro_receive() and skb_gro_receive_list().
> The former moves the incoming skb's frag descriptors into the
> accumulator's last sub-skb via two paths (a direct frag-move loop and
> the head_frag + memcpy path); the latter chains the incoming skb whole
> onto p's frag_list.  Downstream skb_segment() reads only
> skb_shinfo(p)->flags, and skb_segment_list() reuses each sub-skb's
> shinfo as the nskb -- both p and lp must carry the marker.
> 
> The same omission also exists in tcp_clone_payload(), which builds an
> MTU probe skb by moving frag descriptors from skbs on sk_write_queue
> into a freshly allocated nskb.  The helper falls into the same family
> and warrants the same fix for consistency; no TCP TX-side in-place
> writer is currently known to reach a user page through this gap, but
> a future consumer depending on the marker would regress silently.
> 
> Fixes: cef401de7be8 ("net: fix possible wrong checksum generation")
> Fixes: f4c50a4034e6 ("xfrm: esp: avoid in-place decrypt on shared skb frags")
> Suggested-by: Sabrina Dubroca <sd@queasysnail.net>
> Suggested-by: Sultan Alsawaf <sultan@kerneltoast.com>
> Suggested-by: Ben Hutchings <ben@decadent.org.uk>

Since they are asking for credit, I will add them:

Suggested-by: Lin Ma <malin89@huawei.com>
Suggested-by: Jingguo Tan <tanjingguo@huawei.com>

> Cc: stable@vger.kernel.org
> Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
> ---
> Changes in v4:
> - Include the tcp_clone_payload() propagation suggested by Sabrina.
> - Drop the skb_try_coalesce() change; addressed by commit f84eca581739.
> - v3: https://lore.kernel.org/all/agW4vC0r8QOUKtRT@v4bel/
> 
> Changes in v3:
> - Include the skb_gro_receive() audit patch suggested by Sultan
> - v2: https://lore.kernel.org/all/agToIEDI4TaTNLRb@v4bel/
> 
> Changes in v2:
> - Also propagate SHARED_FRAG in skb_try_coalesce() and skb_shift()
> - v1: https://lore.kernel.org/all/agRfuVOeMI5pbHhY@v4bel/
> ---
>  net/core/gro.c        | 4 ++++
>  net/core/skbuff.c     | 3 +++
>  net/ipv4/tcp_output.c | 1 +
>  3 files changed, 8 insertions(+)
> 
> diff --git a/net/core/gro.c b/net/core/gro.c
> index 31d21de5b15a..9f8960789b2c 100644
> --- a/net/core/gro.c
> +++ b/net/core/gro.c
> @@ -213,10 +213,12 @@ int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb)
>  	p->data_len += len;
>  	p->truesize += delta_truesize;
>  	p->len += len;
> +	skb_shinfo(p)->flags |= skbinfo->flags & SKBFL_SHARED_FRAG;
>  	if (lp != p) {
>  		lp->data_len += len;
>  		lp->truesize += delta_truesize;
>  		lp->len += len;
> +		skb_shinfo(lp)->flags |= skbinfo->flags & SKBFL_SHARED_FRAG;
>  	}
>  	NAPI_GRO_CB(skb)->same_flow = 1;
>  	return 0;
> @@ -244,6 +246,8 @@ int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb)
>  	p->truesize += skb->truesize;
>  	p->len += skb->len;
>  
> +	skb_shinfo(p)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
> +
>  	NAPI_GRO_CB(skb)->same_flow = 1;
>  
>  	return 0;
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 9c4e8d331d6d..7cd388504297 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -2248,6 +2248,7 @@ struct sk_buff *__pskb_copy_fclone(struct sk_buff *skb, int headroom,
>  			skb_frag_ref(skb, i);
>  		}
>  		skb_shinfo(n)->nr_frags = i;
> +		skb_shinfo(n)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
>  	}
>  
>  	if (skb_has_frag_list(skb)) {
> @@ -4349,6 +4350,8 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
>  	tgt->ip_summed = CHECKSUM_PARTIAL;
>  	skb->ip_summed = CHECKSUM_PARTIAL;
>  
> +	skb_shinfo(tgt)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
> +
>  	skb_len_add(skb, -shiftlen);
>  	skb_len_add(tgt, shiftlen);
>  
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index f9d8755705f7..6e4bb411dc04 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -2626,6 +2626,7 @@ static int tcp_clone_payload(struct sock *sk, struct sk_buff *to,
>  			todo = min_t(int, skb_frag_size(fragfrom),
>  				     probe_size - len);
>  			len += todo;
> +			skb_shinfo(to)->flags |= skb_shinfo(skb)->flags & SKBFL_SHARED_FRAG;
>  			if (lastfrag &&
>  			    skb_frag_page(fragfrom) == skb_frag_page(lastfrag) &&
>  			    skb_frag_off(fragfrom) == skb_frag_off(lastfrag) +
> -- 
> 2.43.0
> 

  reply	other threads:[~2026-05-15  6:07 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-15  5:55 [PATCH net v4] net: skbuff: propagate shared-frag marker through frag-transfer helpers Hyunwoo Kim
2026-05-15  6:07 ` Hyunwoo Kim [this message]
2026-05-15  6:26 ` Sultan Alsawaf
2026-05-15  6:36   ` Hyunwoo Kim
2026-05-15 15:11     ` Hyunwoo Kim
2026-05-15 16:41 ` Aaron Esau
2026-05-15 20:22   ` Hyunwoo Kim
2026-05-15 21:36     ` Hyunwoo Kim
2026-05-16  0:08       ` Jakub Kicinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aga4KZtvaRQAMv6B@v4bel \
    --to=imv4bel@gmail.com \
    --cc=ben@decadent.org.uk \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=horms@kernel.org \
    --cc=jiayuan.chen@linux.dev \
    --cc=kerneljasonxing@gmail.com \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --cc=malin89@huawei.com \
    --cc=mhal@rbox.co \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sd@queasysnail.net \
    --cc=stable@vger.kernel.org \
    --cc=steffen.klassert@secunet.com \
    --cc=sultan@kerneltoast.com \
    --cc=tanjingguo@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.