Skip to content

Commit 7e59c60

Browse files
edumazetUlrich Hecht
authored andcommitted
tcp: fix __tcp_close() to only send RST when required
[ Upstream commit 5f9238530970f2993b23dd67fdaffc552a2d2e98 ] If the receive queue contains payload that was already received, __tcp_close() can send an unexpected RST. Refine the code to take tp->copied_seq into account, as we already do in tcp recvmsg(). Fixes: 1da177e ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Neal Cardwell <ncardwell@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Link: https://patch.msgid.link/20250903084720.1168904-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Ulrich Hecht <uli@kernel.org>
1 parent 0f9f5ee commit 7e59c60

1 file changed

Lines changed: 5 additions & 4 deletions

File tree

net/ipv4/tcp.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,8 +2347,8 @@ bool tcp_check_oom(struct sock *sk, int shift)
23472347

23482348
void __tcp_close(struct sock *sk, long timeout)
23492349
{
2350+
bool data_was_unread = false;
23502351
struct sk_buff *skb;
2351-
int data_was_unread = 0;
23522352
int state;
23532353

23542354
WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
@@ -2367,11 +2367,12 @@ void __tcp_close(struct sock *sk, long timeout)
23672367
* reader process may not have drained the data yet!
23682368
*/
23692369
while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
2370-
u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq;
2370+
u32 end_seq = TCP_SKB_CB(skb)->end_seq;
23712371

23722372
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
2373-
len--;
2374-
data_was_unread += len;
2373+
end_seq--;
2374+
if (after(end_seq, tcp_sk(sk)->copied_seq))
2375+
data_was_unread = true;
23752376
__kfree_skb(skb);
23762377
}
23772378

0 commit comments

Comments
 (0)