mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: josef@toxicpanda.com
Cc: davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, bpf@vger.kernel.org
Subject: Re: [PATCH net-next v2 3/8] net: skbuff: don't BUG() when skb_copy_bits() fails in copy helpers
Date: Sun, 11 Oct 2026 17:00:45 +0000	[thread overview]
Message-ID: <179173804578.434549.12357016377866471421@kernel.org> (raw)
In-Reply-To: <20261007-b4-skbuff-bug-on-v2-3-b9a5f732895b@toxicpanda.com>

Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.

Critical: 0 · High: 0 · Medium: 1 (1) · Low: 0

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [Medium] skb_try_coalesce() in net/core/skbuff.c stores the unsigned
  `from->len` in `int len`.

Pre-existing issues:
- [Medium] This problem wasn't introduced by this patch, but bounce_skb()
  in drivers/net/xen-netfront.c is an open-coded copy of skb_copy().

--

net: skbuff: don't BUG() when skb_copy_bits() fails in copy helpers

This patch removes the BUG_ON(skb_copy_bits()) calls from skb_copy(),
skb_copy_expand() and skb_try_coalesce(). On failure, skb_copy() and
skb_copy_expand() now free the new skb and return NULL, and
skb_try_coalesce() returns false. skb_try_coalesce() now copies into the
tailroom before calling skb_put(), so that @to is left untouched on failure.

> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index a6821ab139691..ffc78b1a8ab85 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -2201,7 +2201,12 @@ struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
>  	/* Set the tail pointer and length */
>  	skb_put(n, skb->len);
>
> -	BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len));
> +	if (unlikely(skb_copy_bits(skb, -headerlen, n->head,
> +				   headerlen + skb->len))) {
> +		DEBUG_NET_WARN_ON_ONCE(1);
> +		kfree_skb(n);
> +		return NULL;
> +	}
>
>  	skb_copy_header(n, skb);
>  	return n;

[Severity: Medium]
This isn't a bug introduced by this patch, but bounce_skb() in
drivers/net/xen-netfront.c is an open-coded copy of skb_copy(), and it
still has the same BUG_ON():

drivers/net/xen-netfront.c:bounce_skb() {
    ...
	/* Set the data pointer */
	skb_reserve(n, headerlen);
	/* Set the tail pointer and length */
	skb_put(n, skb->len);

	BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len));
    ...
}

bounce_skb() already frees n and returns NULL on the misaligned head path,
and xennet_start_xmit() handles that:

	nskb = bounce_skb(skb);
	if (!nskb)
		goto drop;

Could bounce_skb() get the same NULL-return conversion, either in this
patch or in a follow-up? No later patch in the series touches this site.

The other remaining BUG_ON(skb_copy_bits()) calls in net/ipv4/icmp.c and
net/ipv6/ip6_output.c look like a different case. There, the length is
checked beforehand or the destination fragment is already sized for the
copy.

[ ... ]

> @@ -6233,8 +6243,15 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
>  		return false;
>
>  	if (len <= skb_tailroom(to) && skb_frags_readable(from)) {
> -		if (len)
> -			BUG_ON(skb_copy_bits(from, 0, skb_put(to, len), len));
> +		if (len) {
> +			if (unlikely(skb_copy_bits(from, 0,
> +						   skb_tail_pointer(to),
> +						   len))) {
> +				DEBUG_NET_WARN_ON_ONCE(1);
> +				return false;
> +			}
> +			skb_put(to, len);

[Severity: Medium]
If from->len is corrupt, can copying before skb_put() turn it into an
out-of-bounds write past the tailroom of to?

skb_try_coalesce() stores the unsigned from->len in an int:

	int i, delta, len = from->len;

If from->len is above INT_MAX, len is negative. A negative len passes the
check above, because skb_tailroom() returns int.

It also gets past the first check in skb_copy_bits(). With offset 0 and
len == (int)skb->len, this compares 0 > 0:

	if (offset > (int)skb->len - len)
		goto fault;

After that, copy = start - offset is positive (headlen), copy > len is
true, and so copy is set to the negative len.
skb_copy_from_linear_data_offset() takes a const unsigned int len, so the
memcpy() into skb_tail_pointer(to) becomes roughly 2 GiB. When headlen is 0,
the frag path does the same thing through skb_frag_foreach_page().

Before this patch, skb_put(to, len) ran first. With the offset-based tail
on 64-bit, any from->len in roughly [2^31, 2^32 - tail) hit skb_over_panic()
before anything was copied.

This needs skb metadata that is already corrupt, for example a driver
passing a bogus frag size to skb_add_rx_frag(). No concrete producer has
been found. It also doesn't match this line in the commit message:

  "Copy into the tailroom before skb_put() so that @to is untouched on
   failure."

Would it work to reject len < 0, or to compare from->len as unsigned
against skb_tailroom(to), before the copy?

> +		}
>  		*delta_truesize = 0;
>  		return true;
>  	}

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261007-b4-skbuff-bug-on-v2-0-b9a5f732895b%40toxicpanda.com

  reply	other threads:[~2026-10-11 17:00 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-07 17:35 [PATCH net-next v2 0/8] net: skbuff: replace most BUG_ON()s with error returns Josef Bacik
2026-10-07 17:36 ` [PATCH net-next v2 1/8] net: skbuff: don't BUG() on bad arguments to pskb_expand_head() Josef Bacik
2026-10-07 17:36 ` [PATCH net-next v2 2/8] net: skbuff: don't BUG() on a bad frag_list layout in skb_segment() Josef Bacik
2026-10-11 17:00   ` netdev-bot+sashiko
2026-10-07 17:36 ` [PATCH net-next v2 3/8] net: skbuff: don't BUG() when skb_copy_bits() fails in copy helpers Josef Bacik
2026-10-11 17:00   ` netdev-bot+sashiko [this message]
2026-10-07 17:36 ` [PATCH net-next v2 4/8] net: skbuff: don't BUG() on leftover length in skb_checksum() and friends Josef Bacik
2026-10-11 17:00   ` netdev-bot+sashiko
2026-10-07 17:36 ` [PATCH net-next v2 5/8] net: skbuff: don't BUG() on a bad csum_start in skb_copy_and_csum_dev() Josef Bacik
2026-10-11 17:00   ` netdev-bot+sashiko
2026-10-07 17:36 ` [PATCH net-next v2 6/8] net: skbuff: don't BUG() on leftover length in skb_copy_and_csum_bits() Josef Bacik
2026-10-11 17:00   ` netdev-bot+sashiko
2026-10-07 17:36 ` [PATCH net-next v2 7/8] net: skbuff: don't BUG() on a missing head_frag in skb_zerocopy() Josef Bacik
2026-10-11 17:00   ` netdev-bot+sashiko
2026-10-07 17:36 ` [PATCH net-next v2 8/8] net: skbuff: remove the BUG_ON()s from skb_shift() Josef Bacik

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=179173804578.434549.12357016377866471421@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=bpf@vger.kernel.org \
    --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 \
    /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®