Skip to content
This repository has been archived by the owner on Apr 18, 2024. It is now read-only.

Commit

Permalink
mptcp: Refresh tcp_sock's timestamp when triggering ACK+MP_JOIN retrans
Browse files Browse the repository at this point in the history
Since 4.13, the TCP-stack is maintaining a timestamp for tagging the
skb-stamp. In all the timer handler functions, the TCP-stack is updating
it, so that tcp_transmit_skb can set the right timestamp in the skb.

If we don't make sure that the right timestamp is in the skb,
tp->retrans_stamp will remain 0 in mptcp_ack_retransmit_timer(). Later
on in retransmits_timed_out(), we will thus try to access
tcp_write_queue_head(), which will panic:

foehn login: [   33.114417] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
[   33.114440] IP: retransmits_timed_out.part.8+0xa2/0xc0
[   33.114443] PGD 0 P4D 0
[   33.114445] Oops: 0000 [#1] SMP
[   33.114448] Modules linked in: ipt_REJECT nf_reject_ipv4 xt_multiport nf_log_ipv4 nf_log_common xt_LOG xt_limit xt_nat ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_tcpudp iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat cbc nf_conntrack ceph iptable_filter libceph fscache intel_rapl x86_pkg_temp_thermal coretemp crct10dif_pclmul crc32_pclmul       ghash_clmulni_intel evdev pcbc aesni_intel snd_pcm snd_timer aes_x86_64 crypto_simd snd glue_helper cryptd soundcore pcspkr intel_rapl_perf loop ip_tables x_tables autofs4 xfs libcrc32c crc32c_generic xen_netfront crc32c_intel xen_blkfront
[   33.114479] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W       4.14.2.mptcp #1
[   33.114482] task: ffffffff81c10480 task.stack: ffffffff81c00000
[   33.114486] RIP: e030:retransmits_timed_out.part.8+0xa2/0xc0
[   33.114488] RSP: e02b:ffff8800b7803e40 EFLAGS: 00010246
[   33.114490] RAX: 0000000000000000 RBX: ffff880004d7d3c0 RCX: ffff8800b7811fc0
[   33.114492] RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff880004d7d3c0
[   33.114495] RBP: ffff8800b7803e48 R08: 0000000000000000 R09: 20c49ba5e353f7cf
[   33.114497] R10: ffff8800b7803c78 R11: ffff8800b7006da8 R12: ffff8800b5856248
[   33.114500] R13: ffffffff81cd2980 R14: ffff880004d135c0 R15: ffff880004d7d3c0
[   33.114505] FS:  0000000000000000(0000) GS:ffff8800b7800000(0000) knlGS:0000000000000000
[   33.114508] CS:  e033 DS: 0000 ES: 0000 CR0: 0000000080050033
[   33.114510] CR2: 0000000000000010 CR3: 00000000b571b000 CR4: 0000000000042660
[   33.114513] Call Trace:
[   33.114515]  <IRQ>
[   33.114519]  retransmits_timed_out+0x17/0x20
[   33.114523]  mptcp_ack_handler+0x20e/0x2a0
[   33.114526]  ? mptcp_send_active_reset+0x220/0x220
[   33.114530]  call_timer_fn+0x35/0x130
[   33.114532]  run_timer_softirq+0x1e1/0x450
[   33.114536]  ? handle_percpu_irq+0x43/0x60
[   33.114539]  __do_softirq+0x104/0x28f
[   33.114543]  irq_exit+0xb6/0xc0
[   33.114546]  xen_evtchn_do_upcall+0x30/0x40
[   33.114550]  xen_do_hypervisor_callback+0x29/0x40
[   33.114552]  </IRQ>

Thus, first we need to make sure that the TCP sock's timestamp is
correct by calling tcp_mstamp_refresh().
Second, after tcp_transmit_skb() when clone_it is not set, the skb will
not have the timestamp set. So, we grab it from the TCP-socket instead,
while making 100% sure that it won't be 0.

Cc: Martin Spott <Martin.Spott@mgras.net>
Reported-by: Martin Spott <Martin.Spott@mgras.net>
Fixes: 3811cfd ("Merge tag 'v4.13' into mptcp_trunk")
Signed-off-by: Christoph Paasch <cpaasch@apple.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
  • Loading branch information
cpaasch authored and matttbe committed Dec 8, 2017
1 parent 56732bc commit 5594096
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion net/mptcp/mptcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,8 @@ static void mptcp_ack_retransmit_timer(struct sock *sk)
if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
goto out; /* Routing failure or similar */

tcp_mstamp_refresh(tp);

if (tcp_write_timeout(sk)) {
MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRTO);
tp->mptcp->pre_established = 0;
Expand Down Expand Up @@ -1364,7 +1366,7 @@ static void mptcp_ack_retransmit_timer(struct sock *sk)
}

if (!tp->retrans_stamp)
tp->retrans_stamp = tcp_skb_timestamp(skb);
tp->retrans_stamp = tcp_time_stamp(tp) ? : 1;

icsk->icsk_retransmits++;
icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
Expand Down

0 comments on commit 5594096

Please sign in to comment.