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
> --
next prev parent 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®