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
next prev 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 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.