From: Zoltan Kiss <zoltan.kiss@citrix.com>
To: "netfilter-devel@vger.kernel.org" <netfilter-devel@vger.kernel.org>
Cc: Frediano Ziglio <frediano.ziglio@citrix.com>
Subject: tcp_use_frto crashes on empty tcp_write_queue
Date: Wed, 13 Feb 2013 21:06:53 +0000 [thread overview]
Message-ID: <511C006D.5060605@citrix.com> (raw)
Hi,
I see the following WARN and then crash on 2.6.32.12:
<4>WARNING: at net/ipv4/tcp_timer.c:293 tcp_retransmit_timer+0x5dd/0x630()
...
<1>BUG: unable to handle kernel NULL pointer dereference at (null)
<1>IP: [<c033f2b5>] tcp_use_frto+0x45/0x90
...
<0>Call Trace:
<4> [<c0343ab9>] ? tcp_retransmit_timer+0xd9/0x630
<4> [<c0120e58>] ? __wake_up_common+0x48/0x70
<4> [<c0344580>] ? tcp_write_timer+0xe0/0x1a0
<4> [<c0137fe1>] ? run_timer_softirq+0x151/0x200
<4> [<c02af069>] ? maybe_schedule_tx_action+0x39/0x40
<4> [<c03444a0>] ? tcp_write_timer+0x0/0x1a0
<4> [<c013359a>] ? __do_softirq+0xba/0x180
<4> [<c015e7a7>] ? move_native_irq+0x47/0x50
...
I've checked the code, tcp_use_frto() crashes because
skb = tcp_write_queue_head(sk);
returns a NULL, as the queue is empty, and in the next line:
if (tcp_skb_is_last(sk, skb))
===>
static inline bool tcp_skb_is_last(const struct sock *sk,
const struct sk_buff *skb)
{
return skb_queue_is_last(&sk->sk_write_queue, skb);
}
===>
static inline bool skb_queue_is_last(const struct sk_buff_head *list,
const struct sk_buff *skb)
{
return (skb->next == (struct sk_buff *) list);
}
That skb->next cause the NULL pointer dereference.
I've checked this in upstream, and it seems this would fail in the same
way. Wouldn't it be more reasonable to return from
tcp_retransmit_timer() instead of just signing a WARN? Something like this:
diff -r 7a748d2cb9f1 -r bb8257f0730a net/ipv4/tcp_timer.c
--- a/net/ipv4/tcp_timer.c Wed Feb 13 15:02:50 2013 +0000
+++ b/net/ipv4/tcp_timer.c Wed Feb 13 15:03:18 2013 +0000
@@ -287,11 +287,9 @@ void tcp_retransmit_timer(struct sock *s
struct tcp_sock *tp = tcp_sk(sk);
struct inet_connection_sock *icsk = inet_csk(sk);
- if (!tp->packets_out)
+ if (!tp->packets_out || tcp_write_queue_empty(sk))
goto out;
- WARN_ON(tcp_write_queue_empty(sk));
-
if (!tp->snd_wnd && !sock_flag(sk, SOCK_DEAD) &&
!((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) {
/* Receiver dastardly shrinks window. Our retransmits
Credit goes to Frediano for the patch.
Regards,
Zoli
next reply other threads:[~2013-02-13 21:07 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-13 21:06 Zoltan Kiss [this message]
2013-02-13 21:10 ` tcp_use_frto crashes on empty tcp_write_queue Zoltan Kiss
-- strict thread matches above, loose matches on Subject: below --
2013-02-13 21:09 Zoltan Kiss
2013-02-13 21:37 ` Eric Dumazet
2013-02-13 22:14 ` Zoltan Kiss
2013-02-13 23:24 ` Eric Dumazet
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=511C006D.5060605@citrix.com \
--to=zoltan.kiss@citrix.com \
--cc=frediano.ziglio@citrix.com \
--cc=netfilter-devel@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 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.