This is a note to let you know that I've just added the patch titled tcp: do not forget FIN in tcp_shifted_skb() to the 3.10-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: tcp-do-not-forget-fin-in-tcp_shifted_skb.patch and it can be found in the queue-3.10 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From ab8882f2a3f46b06d8cda14c6aee6f0232307a5e Mon Sep 17 00:00:00 2001 From: Eric Dumazet <edumazet@xxxxxxxxxx> Date: Fri, 4 Oct 2013 10:31:41 -0700 Subject: tcp: do not forget FIN in tcp_shifted_skb() From: Eric Dumazet <edumazet@xxxxxxxxxx> [ Upstream commit 5e8a402f831dbe7ee831340a91439e46f0d38acd ] Yuchung found following problem : There are bugs in the SACK processing code, merging part in tcp_shift_skb_data(), that incorrectly resets or ignores the sacked skbs FIN flag. When a receiver first SACK the FIN sequence, and later throw away ofo queue (e.g., sack-reneging), the sender will stop retransmitting the FIN flag, and hangs forever. Following packetdrill test can be used to reproduce the bug. $ cat sack-merge-bug.pkt `sysctl -q net.ipv4.tcp_fack=0` // Establish a connection and send 10 MSS. 0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +.000 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +.000 bind(3, ..., ...) = 0 +.000 listen(3, 1) = 0 +.050 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> +.000 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 6> +.001 < . 1:1(0) ack 1 win 1024 +.000 accept(3, ..., ...) = 4 +.100 write(4, ..., 12000) = 12000 +.000 shutdown(4, SHUT_WR) = 0 +.000 > . 1:10001(10000) ack 1 +.050 < . 1:1(0) ack 2001 win 257 +.000 > FP. 10001:12001(2000) ack 1 +.050 < . 1:1(0) ack 2001 win 257 <sack 10001:11001,nop,nop> +.050 < . 1:1(0) ack 2001 win 257 <sack 10001:12002,nop,nop> // SACK reneg +.050 < . 1:1(0) ack 12001 win 257 +0 %{ print "unacked: ",tcpi_unacked }% +5 %{ print "" }% First, a typo inverted left/right of one OR operation, then code forgot to advance end_seq if the merged skb carried FIN. Bug was added in 2.6.29 by commit 832d11c5cd076ab ("tcp: Try to restore large SKBs while SACK processing") Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx> Signed-off-by: Yuchung Cheng <ycheng@xxxxxxxxxx> Acked-by: Neal Cardwell <ncardwell@xxxxxxxxxx> Cc: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxx> Acked-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxx> Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- net/ipv4/tcp_input.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1292,7 +1292,10 @@ static bool tcp_shifted_skb(struct sock tp->lost_cnt_hint -= tcp_skb_pcount(prev); } - TCP_SKB_CB(skb)->tcp_flags |= TCP_SKB_CB(prev)->tcp_flags; + TCP_SKB_CB(prev)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags; + if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) + TCP_SKB_CB(prev)->end_seq++; + if (skb == tcp_highest_sack(sk)) tcp_advance_highest_sack(sk, skb); Patches currently in stable-queue which might be from edumazet@xxxxxxxxxx are queue-3.10/tcp-tsq-can-use-a-dynamic-limit.patch queue-3.10/ipv4-fix-ineffective-source-address-selection.patch queue-3.10/net-unix-inherit-sock_pass-cred-sec-flags-from-socket-to-fix-race.patch queue-3.10/net-do-not-call-sock_put-on-timewait-sockets.patch queue-3.10/tcp-must-unclone-packets-before-mangling-them.patch queue-3.10/l2tp-must-disable-bh-before-calling-l2tp_xmit_skb.patch queue-3.10/tcp-do-not-forget-fin-in-tcp_shifted_skb.patch queue-3.10/bnx2x-record-rx-queue-for-lro-packets.patch queue-3.10/tcp-tso-packets-automatic-sizing.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html