Netdev List
 help / color / mirror / Atom feed
From: Ilya Maximets <i.maximets@ovn.org>
To: Jean-Paul Sergent <jpsergent@gmail.com>, netdev@vger.kernel.org
Cc: i.maximets@ovn.org, kuba@kernel.org, kees@kernel.org,
	stable@vger.kernel.org
Subject: Re: [PATCH net v2] net: dst_metadata: fix fortify trap + overread in skb_metadata_dst_cmp
Date: Sat, 3 Oct 2026 15:31:07 +0200	[thread overview]
Message-ID: <787c2c1e-1260-43ae-bee0-9798e1e53c2b@ovn.org> (raw)
In-Reply-To: <20261003005449.2675.3@jpsergent.gmail.com>

On 10/3/26 3:24 AM, Jean-Paul Sergent wrote:
> memcmp: detected buffer overflow: 108 byte read of buffer size 96
>  WARNING: CPU: 0 PID: 15 at lib/string_helpers.c:1036 __fortify_report+0x45/0x60
>   __fortify_panic+0x9/0x10
>   skb_metadata_dst_cmp+0x11b/0x120
>   dev_gro_receive+0x303/0x620
>   gro_receive_skb+0xc5/0x230
>   gro_cell_poll+0x67/0xa0
> 
> Same disease as the tun_dst_unclone fix (4c6d43db2a4d), on the RX
> sibling: kmalloc_flex() in metadata_dst_alloc() sets __counted_by for
> the structure to options_len, which is then initialized to zero, so
> the compiler's view of the metadata_dst tail is 96 bytes at the time
> of the access. Geneve carries 108 bytes of options, and the combined
> struct+options memcmp trips CONFIG_FORTIFY_SOURCE when built with
> clang. Observed live on 6.18.54-talos with Cilium geneve, in
> gro_cell_poll (gro_cells GRO on the geneve device) under sustained
> cross-node RX; the warning is followed by a fatal Oops
> (kernel BUG at lib/string_helpers.c:1043).

This doesn't make sense to me.  The problem in tun_dst_unclone was
at the initialization time, where we couldn't write the options_len
together with the options while the currently stored value is zero.

Here the function just compares two blocks and they must be already
fully initialized and have options_len properly set.  If they have
options, but the length is zero, that's a bug somewhere else.

> 
> While here, fix a related overread: the memcmp length uses
> a->u.tun_info.options_len for BOTH sides, so when b carries fewer
> options than a the comparison reads past b's allocation. Pre-check
> that both sides carry the same options_len

This makes sense and may be the real bug here?  If options actually
have different length for some reason, then the memcmp will rightly
trigger the fortification check as it should.

However, someone more familiar with GRO should probably look at this
to see how the comparison should behave when options are different as
it sounds a little weird that they are.

> and compare the options
> through ip_tunnel_info_opts() so the counted_by view matches the read
> length (the same two-stage shape the unclone fix uses).

This makes no sense.  Single memcmp should work just fine as long as the
compared size doesn't exceed the actual size of both memory regions.

Do you still see the fortification issue trigger with just the length
comparison change?

> 
> Fixes: 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")

This is likely wrong and should point to the commit that added the
tunnel info comparison.

> Cc: stable@vger.kernel.org
> Reported-by: Jean-Paul Sergent <jpsergent@gmail.com>

If you are the author you need a sign-off instead of a reported-by.

Also, you're missing a lot of maintainers in the Cc list.

> Closes: https://lore.kernel.org/netdev/20261003005449.2675.1@jpsergent.gmail.com/

There is no point linking the same thread where you're posting a patch,
it will be linked anyway on commit.

> Assisted-by: LLM
> 
> v2: fix subject prefix to [PATCH net]; no code changes.

This should not be in the commit message.  Also, there should be a link
to the previous version here.

> 
> ---
> 
> Reproduced without the fix: live kernel panic on 6.18.54-talos
> (Cilium geneve, gro_cell_poll) under sustained cross-node RX; trace
> in the report. The fix itself is NOT build-tested - no kernel build
> environment on the reporter's host.
> ---
>  include/net/dst_metadata.h | 28 ++++++++++++++++++++++++----
>  1 file changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
> index f45d1e3..60878ea 100644
> --- a/include/net/dst_metadata.h
> +++ b/include/net/dst_metadata.h
> @@ -115,10 +115,30 @@ static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a,
>  	case METADATA_HW_PORT_MUX:
>  		return memcmp(&a->u.port_info, &b->u.port_info,
>  			      sizeof(a->u.port_info));
> -	case METADATA_IP_TUNNEL:
> -		return memcmp(&a->u.tun_info, &b->u.tun_info,
> -			      sizeof(a->u.tun_info) +
> -					 a->u.tun_info.options_len);
> +	case METADATA_IP_TUNNEL: {
> +		int ret;
> +
> +		/* Options lengths must match, or the options memcmp below
> +		 * would read past b's allocation when b carries fewer
> +		 * options than a.
> +		 */

This is obvious, drop the comment.

> +		if (a->u.tun_info.options_len != b->u.tun_info.options_len)
> +			return 1;
> +		ret = memcmp(&a->u.tun_info, &b->u.tun_info,
> +			     sizeof(a->u.tun_info));
> +		if (ret)
> +			return ret;
> +		/* Compare the options through the flex-array member so the
> +		 * compiler's __counted_by(options_len) view stays consistent
> +		 * with the read length (same shape as the tun_dst_unclone
> +		 * fix); a single memcmp of struct+options trips
> +		 * CONFIG_FORTIFY_SOURCE when options_len is still 0 from
> +		 * allocation time.
> +		 */

This part of the change doesn't make much sense, but anyway, when asking
LLMs to write comments, please ask them to be concise.  There is too much
stuff in there that makes no sense in the context of the code, e.g. the
mentioning of the "tun_dst_unclone fix", and the comment is generally way
too long for what it tries to accomplish.  It should be 2 lines at most
in this particular case.

Same applies to the commit message, there is too much fluff in there that
makes it harder to read.

So, please, do some quality control before sending patches, read what
you're sending.  Don't just shoot out AI slop.  Next person may not be
that kind in their replies.

> +		return memcmp(ip_tunnel_info_opts(&a->u.tun_info),
> +			      ip_tunnel_info_opts(&b->u.tun_info),
> +			      a->u.tun_info.options_len);
> +	}
>  	case METADATA_MACSEC:
>  		return memcmp(&a->u.macsec_info, &b->u.macsec_info,
>  			      sizeof(a->u.macsec_info));

Best regards, Ilya Maximets.

  reply	other threads:[~2026-10-03 13:31 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-03  1:22 [Bug Report] fortify false-positive + real overread in skb_metadata_dst_cmp (geneve, gro_cell_poll) Jean-Paul Sergent
2026-10-03  1:24 ` [PATCH] net: dst_metadata: fix fortify trap + overread in skb_metadata_dst_cmp Jean-Paul Sergent
2026-10-03  1:24   ` [PATCH net v2] " Jean-Paul Sergent
2026-10-03 13:31     ` Ilya Maximets [this message]
2026-10-03 22:50       ` Jean-Paul Sergent
2026-10-04  1:23       ` Jean-Paul Sergent
2026-10-04  1:26     ` netdev-bot+sashiko
2026-10-04  1:26   ` [PATCH] " netdev-bot+sashiko
2026-10-03 22:33 ` [Bug Report] fortify false-positive + real overread in skb_metadata_dst_cmp (geneve, gro_cell_poll) Sasha Levin
2026-10-03 23:05   ` Jean-Paul Sergent
2026-10-04 16:29     ` Sasha Levin

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=787c2c1e-1260-43ae-bee0-9798e1e53c2b@ovn.org \
    --to=i.maximets@ovn.org \
    --cc=jpsergent@gmail.com \
    --cc=kees@kernel.org \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=stable@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox