linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: "Guodeqing (A)" <geffrey.guo@huawei.com>
To: Robin Murphy <robin.murphy@arm.com>, Will Deacon <will@kernel.org>
Cc: "catalin.marinas@arm.com" <catalin.marinas@arm.com>,
	"luke.starrett@broadcom.com" <luke.starrett@broadcom.com>,
	"kernel-team@android.com" <kernel-team@android.com>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: 答复: 答复: [PATCH,v2] arm64: fix the illegal address access in some cases
Date: Fri, 31 Jul 2020 03:04:19 +0000	[thread overview]
Message-ID: <f38221b295c749f99a24cffceeeaadcb@huawei.com> (raw)
In-Reply-To: <621b4e9e-3111-9109-82a1-2c2c14f05ddb@arm.com>



> -----邮件原件-----
> 发件人: Robin Murphy [mailto:robin.murphy@arm.com]
> 发送时间: Thursday, July 30, 2020 17:57
> 收件人: Will Deacon <will@kernel.org>; Guodeqing (A)
> <geffrey.guo@huawei.com>
> 抄送: catalin.marinas@arm.com; kernel-team@android.com;
> linux-arm-kernel@lists.infradead.org; luke.starrett@broadcom.com
> 主题: Re: 答复: [PATCH,v2] arm64: fix the illegal address access in some cases
> 
> On 2020-07-30 09:44, Will Deacon wrote:
> > On Wed, Jul 29, 2020 at 07:05:09AM +0000, Guodeqing (A) wrote:
> >>> On Tue, Jul 28, 2020 at 03:30:50PM +0100, Robin Murphy wrote:
> >>>> On 2020-07-28 14:03, Will Deacon wrote:
> >>>>> Applied to arm64 (for-next/fixes), thanks!
> >>>>>
> >>>>> [1/1] arm64: csum: Reject IP headers with 'ihl' field smaller than five
> >>>>>         https://git.kernel.org/arm64/c/09aaef1c5f50
> >>>>
> >>>> I'm not sure your commit message is entirely right there. AFAICS
> >>>> it's not "the same way as x86" at all - x86 dereferences the first
> >>>> word of iph and returns that as the sum if ihl <= 4 (and thus is
> >>>> still capable of crashing given sufficiently bogus data). I'm not
> >>>> sure where "return 1" came from - if we're going to return nonsense
> >>>> then the mildly more efficient choice of 0 seems just as good.
> >>>
> >>> Argh, yes, that's %1 not $1, so I don't know where the 1 comes from either.
> >>> Geffrey?
> >>>
> >>
> >> The return 1 is just the report of ip checksum error, the return
> >> value 0 means the ip checksum correct. x86 dereferences the first
> >> word of iph and returns that as the sum, this may be just the report of ip
> checksum error too.
> >
> > On the receive path, sure, but the crash was on the transmit path
> > where we're computing the checksum to insert into the header, no?
> >
> >>>> Otherwise it would seem reasonable to jump straight into the
> >>>> word-at-a-time loop if ip_fast_csum() is really expected to cope
> >>>> with more than just genuine IP headers (which should be backed by
> >>>> at least
> >>>> 20 bytes of valid memory regardless of what ihl says).
> >>>
> >>> Either copying the x86 behaviour or WARN_ON_ONCE() and assuming and
> >>> ihl of
> >>> 5 would be my preference, because I agree with you that this feels
> >>> like it shouldn't be happening to start with.
> >>
> >> How about modify the patch like this?
> >>
> >> static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
> >> {
> >> 	__uint128_t tmp;
> >> 	u64 sum;
> >>
> >>      if (unlikely(ihl < 5))
> >>          ihl = 5;
> >
> > I'd probably do:
> >
> > 	/* Callers should really be checking this first */
> > 	if (WARN_ON_ONCE(ihl < 5))
> > 		ihl = 5;
> >
> > because I'd still like to understand what the vlan code is up to.
> >
> >>>> I still think this smells of papering over some other bug that led
> >>>> to a bogus skb getting that far into the transmit stack in the
> >>>> first place - presumably it's all wasted effort anyway since a
> >>>> "header" with no space for a destination address and a deliberately
> >>>> wrong checksum seems unlikely to go very far...
> >>>
> >>> Looking at the ipvlan_start_xmit() path from the backtrace, it looks
> >>> to me like
> >>> ipvlan_get_L3_hdr() returns NULL if the header length is invalid,
> >>> but then
> >>> ipvlan_xmit_mode_l3() ends up calling ipvlan_process_outbound() anyway.
> >>> Hmm. I really don't know enough about VLANs to know what the right
> >>> behaviour is here and I guess just returning NET_XMIT_DROP will
> >>> break something.
> >>
> >> The network maintainer has replied to me, " ip_fast_csum() must be
> >> able to handle any value that could fit in the ihl field of the ip
> >> protocol header. That's not only the most correct logic, but also the
> >> most robust."
> >
> > Is that on a public list somewhere? Would be a good link for the
> > commit message.
> >
> >> This is a fault injection test, the corrupt function of netem is the
> >> emulation of random noise introducing an error in a random position
> >> for a chosen percent of packets to test the network module.the netem
> >> will modify the packet randomly,so the ihl value of ip header may be modified
> to 1.
> >
> > Ok, but netem is running in userspace (right?) and so I still think
> > the network layer can reject the invalid ihl before calling into the
> > checksum code.
> 
> Oh, on second look I realise it's probably not that the fault emanates from
> dereferencing the actual header itself, it'll be from the code just going
> completely bonkers *after* that. I still agree that this case should be avoidable
> entirely on the transmit path, but I accept that robustness for the sake of
> receive does make good sense. How about this?
> 
> Robin.
> 
> ----->8-----
> Subject: [PATCH] arm64: csum: Fix handling of bad packets
> 
> Although iph is expected to point to at least 20 bytes of valid memory, ihl may
> be bogus, for example on reception of a corrupt packet. If it happens to be less
> than 5, we really don't want to run away and dereference 16GB worth of
> memory until it wraps back to exactly zero...
> 
> Fixes: 0e455d8e80aa ("arm64: Implement optimised IP checksum helpers")
> Reported-by: guodeqing <geffrey.guo@huawei.com>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  arch/arm64/include/asm/checksum.h | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/checksum.h
> b/arch/arm64/include/asm/checksum.h
> index b6f7bc6da5fb..93a161b3bf3f 100644
> --- a/arch/arm64/include/asm/checksum.h
> +++ b/arch/arm64/include/asm/checksum.h
> @@ -24,16 +24,17 @@ static inline __sum16 ip_fast_csum(const void *iph,
> unsigned int ihl)  {
>  	__uint128_t tmp;
>  	u64 sum;
> +	int n = ihl; /* we want it signed */
> 
>  	tmp = *(const __uint128_t *)iph;
>  	iph += 16;
> -	ihl -= 4;
> +	n -= 4;
>  	tmp += ((tmp >> 64) | (tmp << 64));
>  	sum = tmp >> 64;
>  	do {
>  		sum += *(const u32 *)iph;
>  		iph += 4;
> -	} while (--ihl);
> +	} while (--n > 0);
> 
Maybe the local temporary variable n is not necessary.

static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
{
	__uint128_t tmp;
	u64 sum;

	tmp = *(const __uint128_t *)iph;
	iph += 16;
	ihl -= 4;           
	tmp += ((tmp >> 64) | (tmp << 64));
	sum = tmp >> 64;
	do {
		sum += *(const u32 *)iph;
		iph += 4;
	} while ((int)(--ihl) > 0);

	sum += ((sum >> 32) | (sum << 32));
	return csum_fold((__force u32)(sum >> 32));
}

Thanks.

>  	sum += ((sum >> 32) | (sum << 32));
>  	return csum_fold((__force u32)(sum >> 32));
> --
> 2.28.0.dirty

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2020-07-31  3:06 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-25  2:08 [PATCH,v2] arm64: fix the illegal address access in some cases guodeqing
2020-07-27 11:47 ` Catalin Marinas
2020-07-27 13:29   ` 答复: " Guodeqing (A)
2020-07-28  9:53     ` Catalin Marinas
2020-07-28 13:03 ` Will Deacon
2020-07-28 14:30   ` Robin Murphy
2020-07-28 15:35     ` Will Deacon
2020-07-29  7:05       ` 答复: " Guodeqing (A)
2020-07-30  8:44         ` Will Deacon
2020-07-30  9:56           ` Robin Murphy
2020-07-30 16:03             ` Will Deacon
2020-07-31  3:04             ` Guodeqing (A) [this message]
2020-07-30 10:49           ` 答复: " Guodeqing (A)

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=f38221b295c749f99a24cffceeeaadcb@huawei.com \
    --to=geffrey.guo@huawei.com \
    --cc=catalin.marinas@arm.com \
    --cc=kernel-team@android.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=luke.starrett@broadcom.com \
    --cc=robin.murphy@arm.com \
    --cc=will@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;
as well as URLs for NNTP newsgroup(s).