mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
tcp: fix __tcp_close() to only send RST when required
[ Upstream commit5f92385309] 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:1da177e4c3("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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
e4ed50b0dc
commit
5eb76d1283
@@ -3099,8 +3099,8 @@ bool tcp_check_oom(const struct sock *sk, int shift)
|
|||||||
|
|
||||||
void __tcp_close(struct sock *sk, long timeout)
|
void __tcp_close(struct sock *sk, long timeout)
|
||||||
{
|
{
|
||||||
|
bool data_was_unread = false;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int data_was_unread = 0;
|
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
|
WRITE_ONCE(sk->sk_shutdown, SHUTDOWN_MASK);
|
||||||
@@ -3119,11 +3119,12 @@ void __tcp_close(struct sock *sk, long timeout)
|
|||||||
* reader process may not have drained the data yet!
|
* reader process may not have drained the data yet!
|
||||||
*/
|
*/
|
||||||
while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
|
while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
|
||||||
u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq;
|
u32 end_seq = TCP_SKB_CB(skb)->end_seq;
|
||||||
|
|
||||||
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
|
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
|
||||||
len--;
|
end_seq--;
|
||||||
data_was_unread += len;
|
if (after(end_seq, tcp_sk(sk)->copied_seq))
|
||||||
|
data_was_unread = true;
|
||||||
__kfree_skb(skb);
|
__kfree_skb(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user