All of lore.kernel.org
 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, andrew+netdev@lunn.ch,
	jgross@suse.com, sstabellini@kernel.org,
	willemdebruijn.kernel@gmail.com, fmancera@suse.de,
	almasrymina@google.com, david.laight.linux@gmail.com,
	netdev@vger.kernel.org, xen-devel@lists.xenproject.org
Subject: Re: [PATCH net-next 10/15] net: skbuff: reject a negative length in skb_copy_and_csum_bits()
Date: Fri, 23 Oct 2026 04:52:09 +0000	[thread overview]
Message-ID: <179273112973.3134.5343458615205155491@kernel.org> (raw)
In-Reply-To: <20261019-b4-skbuff-bug-on-followups-v1-10-41dbef50b9f7@toxicpanda.com>

Thank you for your contribution! Sashiko AI review found more severe
issue(s) in other patches of this series. This mail is only an FYI, in case
you want to address the nit picks below when you respin.

Low priority / nit picks for your consideration:

- [Low] The commit message's reason for dropping the `if (len > 0)` guard
  on the final zero-fill in skb_copy_and_csum_bits() (net/core/skbuff.c)…
- [Low] The patch narrows the zero-fill promise in
  skb_copy_and_csum_bits()'s kernel-doc: "on -EFAULT the part of @to…

--

net: skbuff: reject a negative length in skb_copy_and_csum_bits()

This commit makes skb_copy_and_csum_bits() return -EINVAL, with a
DEBUG_NET_WARN_ON_ONCE(), when it is given a negative len. It also drops
the len > 0 guard on the final zero-fill. The kernel-doc now promises the
zero-fill only for -EFAULT.

Link: https://lore.kernel.org/all/20261007-b4-skbuff-bug-on-v2-0-b9a5f732895b@toxicpanda.com/

> Commit 417261779eab ("net: skbuff: don't BUG() on leftover length in
> skb_copy_and_csum_bits()") guards its zero-fill against a negative @len
> from a broken caller, but such a @len never gets that far.  The head,
> frag and frag_list copies all clamp their length to @len, so a negative
> one has already turned into a huge copy, or an endless frag walk, by
> then.

[Severity: Low]
Is this an accurate description of the old code? The head, frag and
frag_list copies clamp to len only when they run. All three are skipped
when offset is at or past the end of the skb's data.

Take a linear skb with no frags, offset == skb->len and len == -1:

    copy = start - offset;                            /* 0, no head copy */
    for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)   /* no frags */
    skb_walk_frags(skb, frag_iter)                    /* empty */

In the parent commit, the negative len then reaches the final block
unchanged:

net/core/skbuff.c:skb_copy_and_csum_bits() {
    ...
	if (unlikely(len)) {
		DEBUG_NET_WARN_ON_ONCE(1);
		/* Don't hand the caller a buffer with stale bytes in it. */
		if (len > 0)
			memset(to, 0, len);
		return -EFAULT;
	}
    ...
}

There, the len > 0 check is what prevents a memset of close to SIZE_MAX
bytes.

The code change itself looks right, because the new check on entry keeps
len non-negative for the rest of the function. The Fixes: tag relies on
this description of what 417261779eab guarded, though. Could the commit
message say that the guard only covered the final zero-fill and not the
clamped copies?

> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 782a6bacd568..56cec58bccb7 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -3678,9 +3678,10 @@ EXPORT_SYMBOL(skb_checksum);
>   *	@len: number of bytes to copy
>   *	@csump: where to store the checksum of the copied bytes
>   *
> - *	Return: 0 on success, or -EFAULT if @skb has unreadable frags or runs
> - *	out before @len does.  On failure *@csump is not set and the part of
> - *	@to that couldn't be filled is zeroed.
> + *	Return: 0 on success, -EINVAL if @len is negative, or -EFAULT if @skb
> + *	has unreadable frags or runs out before @len does.  On failure *@csump
> + *	is not set, and on -EFAULT the part of @to that couldn't be filled is
> + *	zeroed.
>   */
>  int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
>  			   u8 *to, int len, __wsum *csump)
> @@ -3692,6 +3693,14 @@ int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
>  	__wsum csum = 0;
>  	int err;
>  
> +	/* Everything below clamps copies to @len, so a negative one would
> +	 * turn into a huge copy.
> +	 */
> +	if (unlikely(len < 0)) {
> +		DEBUG_NET_WARN_ON_ONCE(1);
> +		return -EINVAL;
> +	}

[Severity: Low]
This early return leaves to untouched, and the kernel-doc above now
promises the zero-fill only for -EFAULT. Does skb_copy_and_csum_dev() need
an update as well? Its comment still says that any failure zeroes the
buffer:

net/core/skbuff.c:skb_copy_and_csum_dev() {
    ...
	csum = 0;
	/* On failure the rest of @to is zeroed; leave the checksum alone so
	 * the frame goes out with a bad one.
	 */
	if (csstart != skb->len &&
	    skb_copy_and_csum_bits(skb, csstart, to + csstart,
				   skb->len - csstart, &csum))
		return;
    ...
}

The drivers that call it (8139too, via-rhine, sc92031, ep93xx, ec_bhf,
ksz884x) transmit to after it returns. The csstart checks keep
skb->len - csstart non-negative as an unsigned value, but they don't keep
it within INT_MAX. A corrupt skb with more than INT_MAX bytes past csstart
would get -EINVAL here, and the bytes after csstart would go out stale.

That also goes against the first patch in the series ("net: skbuff: make
skb_copy_and_csum_bits() report unreadable frags"), which says "The
zero-fill stays, so a caller that does send the buffer still doesn't leak
anything."

The drivers' own size limits keep valid skbs from getting here. Before
this patch, the same corrupt input caused a huge copy instead. The comment
in skb_copy_and_csum_dev() is still unchanged at the end of the series,
including after "net: update comments that still describe the skb
BUG_ON()s".

Could that comment be updated? Alternatively, skb_copy_and_csum_dev()
could zero the rest of to itself when the helper fails.

[ ... ]

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261019-b4-skbuff-bug-on-followups-v1-0-41dbef50b9f7%40toxicpanda.com


  reply	other threads:[~2026-10-23  4:52 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 13:50 [PATCH net-next 00/15] net: skbuff: follow-ups to the BUG_ON() removal Josef Bacik
2026-10-19 13:50 ` [PATCH net-next 01/15] net: skbuff: make skb_copy_and_csum_bits() report unreadable frags Josef Bacik
2026-10-23  4:51   ` netdev-bot+sashiko
2026-10-19 13:50 ` [PATCH net-next 02/15] net: skbuff: add skb_checksum_full() that reports failure Josef Bacik
2026-10-23  4:51   ` netdev-bot+sashiko
2026-10-23 14:01   ` Mina Almasry
2026-10-19 13:50 ` [PATCH net-next 03/15] net: skbuff: fail checksum validation when the skb can't be checksummed Josef Bacik
2026-10-23  4:51   ` netdev-bot+sashiko
2026-10-23 14:12     ` Mina Almasry
2026-10-23 14:37   ` Mina Almasry
2026-10-19 13:50 ` [PATCH net-next 04/15] net: skbuff: fail segmentation when a segment " Josef Bacik
2026-10-23  4:52   ` netdev-bot+sashiko
2026-10-23 14:14   ` Mina Almasry
2026-10-19 13:50 ` [PATCH net-next 05/15] net: skbuff: fail pskb_trim_rcsum() when it can't checksum the tail Josef Bacik
2026-10-23  4:52   ` netdev-bot+sashiko
2026-10-19 13:50 ` [PATCH net-next 06/15] net: skbuff: add skb_crc32c_full() that reports failure Josef Bacik
2026-10-23  4:52   ` netdev-bot+sashiko
2026-10-19 13:50 ` [PATCH net-next 07/15] net: skbuff: let skb_zerocopy() copy a short skb without head_frag Josef Bacik
2026-10-23  4:52   ` netdev-bot+sashiko
2026-10-19 13:50 ` [PATCH net-next 08/15] net: skbuff: make skb_try_coalesce()'s len unsigned Josef Bacik
2026-10-23  4:52   ` netdev-bot+sashiko
2026-10-19 13:50 ` [PATCH net-next 09/15] net: skbuff: check csum_start against len in skb_copy_and_csum_dev() Josef Bacik
2026-10-23  4:52   ` netdev-bot+sashiko
2026-10-19 13:50 ` [PATCH net-next 10/15] net: skbuff: reject a negative length in skb_copy_and_csum_bits() Josef Bacik
2026-10-23  4:52   ` netdev-bot+sashiko [this message]
2026-10-19 13:50 ` [PATCH net-next 11/15] net: skbuff: refuse to segment a nested frag_list Josef Bacik
2026-10-20 20:09   ` Willem de Bruijn
2026-10-23  4:52   ` netdev-bot+sashiko
2026-10-19 13:50 ` [PATCH net-next 12/15] net: test the frag_list layouts skb_segment() refuses Josef Bacik
2026-10-20 20:17   ` Willem de Bruijn
2026-10-19 13:50 ` [PATCH net-next 13/15] xen-netfront: don't BUG() when skb_copy_bits() fails in bounce_skb() Josef Bacik
2026-10-19 13:50 ` [PATCH net-next 14/15] net/tls: don't BUG() on leftover length in __skb_nsg() Josef Bacik
2026-10-19 15:12   ` Mina Almasry
2026-10-19 16:22     ` Willem de Bruijn
2026-10-19 16:27       ` Mina Almasry
2026-10-23  4:52   ` netdev-bot+sashiko
2026-10-19 13:50 ` [PATCH net-next 15/15] net: update comments that still describe the skb BUG_ON()s Josef Bacik
2026-10-19 15:09   ` Mina Almasry

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=179273112973.3134.5343458615205155491@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=almasrymina@google.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=david.laight.linux@gmail.com \
    --cc=edumazet@kernel.org \
    --cc=fmancera@suse.de \
    --cc=horms@kernel.org \
    --cc=jgross@suse.com \
    --cc=josef@toxicpanda.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sstabellini@kernel.org \
    --cc=willemdebruijn.kernel@gmail.com \
    --cc=xen-devel@lists.xenproject.org \
    /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.