Patch "tcp: don't free a FIN sk_buff in tcp_remove_empty_skb()" has been added to the 4.19-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    tcp: don't free a FIN sk_buff in tcp_remove_empty_skb()

to the 4.19-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-don-t-free-a-fin-sk_buff-in-tcp_remove_empty_skb.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 38b85e8c7b932e05974b9c5a009a7f359d400922
Author: Jon Maxwell <jmaxwell37@xxxxxxxxx>
Date:   Mon Oct 25 10:59:03 2021 +1100

    tcp: don't free a FIN sk_buff in tcp_remove_empty_skb()
    
    [ Upstream commit cf12e6f9124629b18a6182deefc0315f0a73a199 ]
    
    v1: Implement a more general statement as recommended by Eric Dumazet. The
    sequence number will be advanced, so this check will fix the FIN case and
    other cases.
    
    A customer reported sockets stuck in the CLOSING state. A Vmcore revealed that
    the write_queue was not empty as determined by tcp_write_queue_empty() but the
    sk_buff containing the FIN flag had been freed and the socket was zombied in
    that state. Corresponding pcaps show no FIN from the Linux kernel on the wire.
    
    Some instrumentation was added to the kernel and it was found that there is a
    timing window where tcp_sendmsg() can run after tcp_send_fin().
    
    tcp_sendmsg() will hit an error, for example:
    
    1269 ▹       if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))↩
    1270 ▹       ▹       goto do_error;↩
    
    tcp_remove_empty_skb() will then free the FIN sk_buff as "skb->len == 0". The
    TCP socket is now wedged in the FIN-WAIT-1 state because the FIN is never sent.
    
    If the other side sends a FIN packet the socket will transition to CLOSING and
    remain that way until the system is rebooted.
    
    Fix this by checking for the FIN flag in the sk_buff and don't free it if that
    is the case. Testing confirmed that fixed the issue.
    
    Fixes: fdfc5c8594c2 ("tcp: remove empty skb from write queue in error cases")
    Signed-off-by: Jon Maxwell <jmaxwell37@xxxxxxxxx>
    Reported-by: Monir Zouaoui <Monir.Zouaoui@mail.schwarz>
    Reported-by: Simon Stier <simon.stier@mail.schwarz>
    Reviewed-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 769e1f683471a..4dce1b418acc2 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -952,7 +952,7 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
  */
 static void tcp_remove_empty_skb(struct sock *sk, struct sk_buff *skb)
 {
-	if (skb && !skb->len) {
+	if (skb && TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) {
 		tcp_unlink_write_queue(skb, sk);
 		if (tcp_write_queue_empty(sk))
 			tcp_chrono_stop(sk, TCP_CHRONO_BUSY);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux