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 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).