From: Michael Tokarev <mjt@tls.msk.ru>
To: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Linux-kernel <linux-kernel@vger.kernel.org>,
netdev <netdev@vger.kernel.org>
Subject: Re: [Security, resend] Instant crash with rtl8169 and large packets
Date: Mon, 08 Jun 2009 20:26:46 +0400 [thread overview]
Message-ID: <4A2D3BC6.3040904@msgid.tls.msk.ru> (raw)
In-Reply-To: <4A2D3568.6010901@gmail.com>
Eric Dumazet wrote:
> Michael Tokarev a écrit :
>> Eric Dumazet wrote:
>>> Michael Tokarev a écrit :
>> []
>>>>>> The situation is very simple: with an RTL8169 (probably
>>>>>> onboard) GigE card which, by default, is configured to
>>>>>> have MTU (maximal transmission unit) to be 1500 bytes,
>>>>>> it's *trivial* to instantly crash the machine by sending
>>>>>> it a *single* packet of size >1500 bytes (provided the
>>>>>> network switch can handle jumbo frames).
>> []
>>> OK, 2nd try then :)
>>> diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
>>> index e94316b..9080b08 100644
>>> --- a/drivers/net/r8169.c
>>> +++ b/drivers/net/r8169.c
>>> @@ -3495,7 +3495,8 @@ static int rtl8169_rx_interrupt(struct
>>> net_device *dev,
>>> * frames. They are seen as a symptom of over-mtu
>>> * sized frames.
>>> */
>>> - if (unlikely(rtl8169_fragmented_frame(status))) {
>>> + if (unlikely(rtl8169_fragmented_frame(status) ||
>>> + (unsigned int)pkt_size > tp->rx_buf_sz)) {
>>> dev->stats.rx_dropped++;
>>> dev->stats.rx_length_errors++;
>>> rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
>> This one behaves much better. There's no instant crash anymore, and the
>> 'dropped' and 'frame' stats in ifconfig gets incremented with each ping.
>>
>> It fails down the line however. I wasn't able to reply to this email after
>> doing the ping test with the above change (no more large packets were
>> sent).
>> With OOPSes like this one:
>>
>> general protection fault: 0000 [#1] SMP
[]
>> [<ffffffff803dbc7f>] ? skb_release_data+0xaf/0xe0
>> [<ffffffff803db911>] ? __kfree_skb+0x11/0xa0
>> [<ffffffff80418a88>] ? tcp_recvmsg+0x6d8/0x950
[]
>> Looks like some memory corruption. And most probably it is in
>> that error path in r8169 driver - it is the only new codepath
>> which were executed here. The problem is quite repeatable -
>> after sending a single large ping system starts behaving like
>> the above at random.
[]
> Hmm... this code path is not new, I believe your adapter is buggy, because it
> is overwriting part of memory it should not touch at all.
>
> When this driver queues a skb in rx queue, it tells NIC the max size of the skb,
> and apparently NIC happily delivers packets with larger sizes, so probably DMA
> wrote data past end of skb data.
That's a very likely situation.
> Try to change
>
> static void rtl_set_rx_max_size(void __iomem *ioaddr)
> RTL_W16(RxMaxSize, 16383);
>
> to ->
>
> RTL_W16(RxMaxSize, RX_BUF_SIZE);
>
> (But it will probably break jumbo frames rx as well)
(RX_BUF_SIZE is defined as 1536).
Aha, so it should set some flags instead (as were tested in your
first try), for packets larger than that. Makes sense.
But if we told the NIC that we can receive 16K buffers, and it
delivered 3K packet to us, we've got some memory corruption...
I.e., the problem is that we told the driver that we can handle
16k buffers but actually we had only 1500, no?
Lemme check this all...
Setting RxMaxSize to RX_BUF_SIZE indeed solved the problem, --
I don't see random corruptions like the last one above.
But after setting RxMaxSize to 2500, I can trigger your 2nd
check/patch condition (for pkt_size > tp->rx_buf_sz) for
packets <2500 in size, and your *first* check/patch condition
(RxRES | RxRWT | RxRUNT | RxCRC | RxFOVF) for packets >2500
in size.
So to me (who has no knowledge about hardware at all), it looks
like the card behaves quite correctly.
Also note that I've seen this behavior on several different
machines. Here @home where I'm doing this all testing I've
Asus M3A78-EM motherboard (AMD780), and the second one is
Gigabyte GA-MA74GM-S2H (AMD740) - both behaves very similarly.
Both are AMD7xx, but I've seen the same problem on Intel-based
machines too.
I'll try out some more tests later today. (And there's another
issue with these NICs -- the famous, quite frequent under load
"NETDEV WATCHDOG: eth0 (r8169): transmit timed out" errors, which
are quite annoying... Also shown by both the above-mentioned mobos
and by other machines).
Thanks!
/mjt
next prev parent reply other threads:[~2009-06-08 16:26 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-08 13:25 [Security, resend] Instant crash with rtl8169 and large packets Michael Tokarev
2009-06-08 14:27 ` Eric Dumazet
2009-06-08 14:53 ` Michael Tokarev
2009-06-08 15:06 ` Eric Dumazet
2009-06-08 15:37 ` Michael Tokarev
2009-06-08 15:59 ` Eric Dumazet
2009-06-08 16:26 ` Michael Tokarev [this message]
2009-06-08 17:30 ` Eric Dumazet
2009-06-08 19:28 ` Michael Tokarev
2009-06-08 19:57 ` Michael Tokarev
2009-06-08 21:17 ` Eric Dumazet
2009-06-08 21:27 ` Michael Tokarev
2009-06-09 11:20 ` Krzysztof Halasa
2009-06-08 22:02 ` Francois Romieu
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=4A2D3BC6.3040904@msgid.tls.msk.ru \
--to=mjt@tls.msk.ru \
--cc=eric.dumazet@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@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;
as well as URLs for NNTP newsgroup(s).