mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Charalampos Mitrodimas <charmitro@posteo.net>
To: Simon Horman <horms@kernel.org>
Cc: Steffen Klassert <steffen.klassert@secunet.com>,
	 Herbert Xu <herbert@gondor.apana.org.au>,
	 "David S. Miller" <davem@davemloft.net>,
	David Ahern <dsahern@kernel.org>,
	 Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>,
	 Paolo Abeni <pabeni@redhat.com>,
	netdev@vger.kernel.org,  linux-kernel@vger.kernel.org,
	syzbot+01b0667934cdceb4451c@syzkaller.appspotmail.com
Subject: Re: [PATCH net v2] net: ipv6: fix buffer overflow in AH output
Date: Mon, 28 Jul 2025 12:36:18 +0000	[thread overview]
Message-ID: <871pq05w74.fsf@posteo.net> (raw)
In-Reply-To: <20250728113656.GA1367887@horms.kernel.org>

Simon Horman <horms@kernel.org> writes:

> On Sun, Jul 27, 2025 at 09:51:40PM +0000, Charalampos Mitrodimas wrote:
>> Fix a buffer overflow where extension headers are incorrectly copied
>> to the IPv6 address fields, resulting in a field-spanning write of up
>> to 40 bytes into a 16-byte field (IPv6 address).
>> 
>>   memcpy: detected field-spanning write (size 40) of single field "&top_iph->saddr" at net/ipv6/ah6.c:439 (size 16)
>>   WARNING: CPU: 0 PID: 8838 at net/ipv6/ah6.c:439 ah6_output+0xe7e/0x14e0 net/ipv6/ah6.c:439
>> 
>> The issue occurs in ah6_output() and ah6_output_done() where the code
>> attempts to save/restore extension headers by copying them to/from the
>> IPv6 source/destination address fields based on the CONFIG_IPV6_MIP6
>> setting.
>> 
>> Reported-by: syzbot+01b0667934cdceb4451c@syzkaller.appspotmail.com
>> Closes: https://syzkaller.appspot.com/bug?extid=01b0667934cdceb4451c
>> Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
>> ---
>> Changes in v2:
>> - Link correct syzbot dashboard link in patch tags
>> - Link to v1: https://lore.kernel.org/r/20250727-ah6-buffer-overflow-v1-1-1f3e11fa98db@posteo.net
>
> You posted two versions of this patch within a few minutes.
> Please don't do that. Rather, please wait 24h to allow review to occur.

I'm aware. The reason for posting the second version so soon was because
I did not want people to get confused about which syzbot report this
solves, as the one in v1 was the wrong.

>
> https://docs.kernel.org/process/maintainer-netdev.html
>
>> ---
>>  net/ipv6/ah6.c | 24 +++++-------------------
>>  1 file changed, 5 insertions(+), 19 deletions(-)
>> 
>> diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
>> index eb474f0987ae016b9d800e9f83d70d73171b21d2..0fa3ed3c64c4ed1a1907d73fb3477e11ef0bd5b8 100644
>> --- a/net/ipv6/ah6.c
>> +++ b/net/ipv6/ah6.c
>> @@ -301,13 +301,8 @@ static void ah6_output_done(void *data, int err)
>>  	memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
>>  	memcpy(top_iph, iph_base, IPV6HDR_BASELEN);
>>  
>> -	if (extlen) {
>> -#if IS_ENABLED(CONFIG_IPV6_MIP6)
>> -		memcpy(&top_iph->saddr, iph_ext, extlen);
>> -#else
>> -		memcpy(&top_iph->daddr, iph_ext, extlen);
>> -#endif
>> -	}
>> +	if (extlen)
>> +		memcpy((u8 *)(top_iph + 1), iph_ext, extlen);
>
> nit: The cast seems unnecessary.

You're right.

>
>>  
>>  	kfree(AH_SKB_CB(skb)->tmp);
>>  	xfrm_output_resume(skb->sk, skb, err);
>
> I am somewhat confused about both your description of the problem,
> and the solution.
>
> It seems to me that:
>
> 1. The existing memcpy (two variants, depending on CONFIG_IPV6_MIP6),
>    are copying data to the correct location (else this fetuare would not work).
> 2. Due to the structure layout of struct ipv6hdr, syzcaller is warning that
>    the write overruns he end of the structure.
> 3. Although that syzcaller is correct about the structure field being too
>    small for the data, there is space to write into.
>
> Are these three points correct?

Yes, you're right. The code works because extension headers come right
after the IPv6 header in memory, and the warning is a false positive. I
now see my patch could break things by only copying extension headers
instead of both addresses and extension headers like the original code
does.

>
> If so, I don't think it is correct to describe this as a buffer overflow
> in the patch description. But rather a warning about one, that turns
> out to be a false positive. And if so, I think this patch is more of
> a clean-up for ipsec-next, rather than a fix for ipsec or net.

Yes this can be changed to mention something with "field-spanning memcpy
warning".

>
> Also, if so, I don't think your patch is correct because it changes the
> destination address that data is written to from towards the end of
> top_iph, to immediately after the end of top_iph (which is further into
> overflow territory, if that is the problem).
>
> I'm unsure of a concise way to resolve this problem, but it seems to me
> that the following is correct (compile tested only!):
>
> diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
> index eb474f0987ae..5bf22b007053 100644
> --- a/net/ipv6/ah6.c
> +++ b/net/ipv6/ah6.c
> @@ -303,10 +303,10 @@ static void ah6_output_done(void *data, int err)
>  
>  	if (extlen) {
>  #if IS_ENABLED(CONFIG_IPV6_MIP6)
> -		memcpy(&top_iph->saddr, iph_ext, extlen);
> -#else
> -		memcpy(&top_iph->daddr, iph_ext, extlen);
> +		top_iph->saddr = iph_ext->saddr;
>  #endif
> +		top_iph->daddr = iph_ext->daddr;
> +		memcpy(top_iph + 1, &iph_ext->hdrs, extlen - sizeof(*iph_ext));
>  	}
>  
>  	kfree(AH_SKB_CB(skb)->tmp);

This is much better actually, thanks a lot. I tested it with the syzbot
reproducer and no issues were found.

>
> I would also suggest adding a helper (or two), to avoid (repeatedly) open
> coding whatever approach is taken.

I'll do that and go on with a patch targetting ipsec-next. Is it okay to
keep the the versioning or it should a completely new patch?

>
> ...

Thanks,
C. Mitrodimas

  reply	other threads:[~2025-07-28 12:36 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-27 21:51 Charalampos Mitrodimas
2025-07-28 11:36 ` Simon Horman
2025-07-28 12:36   ` Charalampos Mitrodimas [this message]
2025-07-28 13:50     ` Simon Horman

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=871pq05w74.fsf@posteo.net \
    --to=charmitro@posteo.net \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=steffen.klassert@secunet.com \
    --cc=syzbot+01b0667934cdceb4451c@syzkaller.appspotmail.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®