mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
To: shao.mingyin@zte.com.cn,  davem@davemloft.net,
	 edumazet@kernel.org,  kuba@kernel.org,  pabeni@redhat.com,
	 netdev@vger.kernel.org,  josef@toxicpanda.com
Cc: horms@kernel.org,  josef@toxicpanda.com,  willemb@google.com,
	 almasrymina@google.com,  linux-kernel@vger.kernel.org
Subject: Re: [PATCH] net: skbuff: don't BUG() when skb_copy_bits() fails in __pskb_pull_tail
Date: Sat, 07 Nov 2026 10:04:25 -0500	[thread overview]
Message-ID: <willemdebruijn.kernel.703e96022339@gmail.com> (raw)
In-Reply-To: <20261107215051120CrLjo_cGXWfdJxXk4ae8s@zte.com.cn>

shao.mingyin@ wrote:
> From: Shao Mingyin <shao.mingyin@zte.com.cn>
> 
> __pskb_pull_tail() BUG()s if skb_copy_bits() returns an error.
> skb_copy_bits() fails when the lengths do not add up, or when a
> frag_list child carries unreadable frags (devmem net_iov, commit
> 65249feb6b3d ("net: add support for skbs with unreadable frags")).  The
> top-level check above does not cover frag_list children, and
> skb_gro_receive() links them without propagating skb->unreadable, so a
> mixed skb trips the BUG().
> 
> Nothing has been committed at that point, so return NULL the way the
> rest of the function already handles failures, with a
> DEBUG_NET_WARN_ON_ONCE() for debug kernels.  skb_condense(), the one
> net/core caller that ignores the return, now checks it and keeps the
> original truesize when the pull fails, as the frags are still there.
> 
> The other direct callers that ignore the return do not build a
> frag_list child: xen-netfront drops the skb when the failed pull leaves
> nr_frags at MAX_SKB_FRAGS, and niu, mlx5 and ftmac100 pull at most what
> their own skb holds.  A length mismatch there is a driver bug, which
> the debug warning reports.
> 
> This is the separate change that commit 279877d86c82 ("net: skbuff:
> don't BUG() when skb_copy_bits() fails in copy helpers") left for the
> callers; the audit is above.  No Fixes: tag and no stable marking: the
> mixed skb is an invariant violation, not a regression, and this is a
> net-next hardening in the BUG_ON() removal series.

In the series, Josef reported

  Two BUG_ON()s are left on purpose.  __pskb_pull_tail() and
  skb_pull_rcsum() have callers that can't otherwise fail, so they don't
  check the return.  Some of them would carry on and BUG() somewhere
  else, or push back a pull that never happened.  Those need their
  callers fixed first and will come as separate series.

> Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
> ---
>  net/core/skbuff.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> Tested on 7.3.0-next-20261030 (QEMU/TCG guest).  QEMU has no devmem
> (net_iov) backend, so a TEST-ONLY hook (applied to both kernels, not
> part of this patch) fabricates an skb whose frag_list child carries an
> unreadable frag, then calls the real __pskb_pull_tail() on it at
> late_initcall time: skb_copy_bits() recurses into the child, sees the
> unreadable frag and fails.  The hook then calls skb_condense() on the
> same skb, so the failed pull must not shrink truesize.
> 
>   unpatched                             patched
>   kernel BUG at                         __pskb_pull_tail() returns NULL,
>   net/core/skbuff.c:2903                skb_condense() keeps truesize 960,
>                                         boot continues, no BUG
> 
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 48f676411724..8a200252ef93 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -2900,8 +2900,11 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta)
>  			return NULL;
>  	}
>  
> -	BUG_ON(skb_copy_bits(skb, skb_headlen(skb),
> -			     skb_tail_pointer(skb), delta));
> +	if (unlikely(skb_copy_bits(skb, skb_headlen(skb),
> +				   skb_tail_pointer(skb), delta))) {
> +		DEBUG_NET_WARN_ON_ONCE(1);
> +		return NULL;
> +	}
>  
>  	/* Optimization: no fragments, no reasons to preestimate
>  	 * size of pulled pages. Superb.
> @@ -7218,7 +7221,8 @@ void skb_condense(struct sk_buff *skb)
>  			return;
>  
>  		/* Nice, we can free page frag(s) right now */
> -		__pskb_pull_tail(skb, skb->data_len);
> +		if (!__pskb_pull_tail(skb, skb->data_len))
> +			return;	/* frags are still there, keep truesize */
>  	}
>  	/* At this point, skb->truesize might be over estimated,
>  	 * because skb had a fragment, and fragments do not tell
> --



  reply	other threads:[~2026-11-07 15:04 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-07 13:50 shao.mingyin
2026-11-07 15:04 ` Willem de Bruijn [this message]
2026-11-07 15:22   ` shao.mingyin

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=willemdebruijn.kernel.703e96022339@gmail.com \
    --to=willemdebruijn.kernel@gmail.com \
    --cc=almasrymina@google.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=josef@toxicpanda.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=shao.mingyin@zte.com.cn \
    --cc=willemb@google.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®