sk->sk_shutdown = SHUTDOWN_MASK; 2) After that the process (socket owner) tries to write something to that socket and "inet_autobind" sets a _new_ (which differs from the original!) port number for the socket: Call Trace: [] inet_bind_hash+0x33/0x5f [] inet_csk_get_port+0x216/0x268 [] inet_autobind+0x22/0x8f [] inet_sendmsg+0x27/0x57 [] do_sock_write+0xae/0xea [] sock_writev+0xdc/0xf6 [] _spin_lock_irqsave+0x9/0xe [] __pollwait+0x0/0xdd [] default_wake_function+0x0/0xe [] autoremove_wake_function+0x0/0x2e [] do_readv_writev+0x163/0x274 [] thread_return+0x13a/0x174 [] tcp_poll+0x0/0x1c9 [] audit_syscall_entry+0x180/0x1b3 [] sys_writev+0x49/0xe4 [] tracesys+0xd5/0xe0 3) sendmsg fails at last with -EPIPE (=> 'write' returns -EPIPE in userspace): F: tcp_sendmsg1 -EPIPE: sk=ffff81000bda00d0, sport=49847, old_state=7, new_state=7, sk_err=0, sk_shutdown=3 Call Trace: [] tcp_sendmsg+0xcb/0xe87 [] release_sock+0x10/0xae [] vgacon_cursor+0x0/0x1a7 [] inet_autobind+0x8b/0x8f [] do_sock_write+0xae/0xea [] sock_writev+0xdc/0xf6 [] _spin_lock_irqsave+0x9/0xe [] __pollwait+0x0/0xdd [] default_wake_function+0x0/0xe [] autoremove_wake_function+0x0/0x2e [] do_readv_writev+0x163/0x274 [] thread_return+0x13a/0x174 [] tcp_poll+0x0/0x1c9 [] audit_syscall_entry+0x180/0x1b3 [] sys_writev+0x49/0xe4 [] tracesys+0xd5/0xe0 tcp_sendmsg() ... /* Wait for a connection to finish. */ if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) { int old_state = sk->sk_state; if ((err = sk_stream_wait_connect(sk, &timeo)) != 0) { if (f_d && (err == -EPIPE)) { printk("F: tcp_sendmsg1 -EPIPE: sk=%p, sport=%u, old_state=%d, new_state=%d, " "sk_err=%d, sk_shutdown=%d\n", sk, ntohs(inet_sk(sk)->sport), old_state, sk->sk_state, sk->sk_err, sk->sk_shutdown); dump_stack(); } goto out_err; } } ... 4) Then the process (socket owner) understands that it's time to close that socket and does that (and thus triggers sending reset packet): Call Trace: ... [] dev_queue_xmit+0x343/0x3d6 [] ip_output+0x351/0x384 [] dst_output+0x0/0xe [] ip_queue_xmit+0x567/0x5d2 [] vprintk+0x21/0x33 [] check_poison_obj+0x2e/0x206 [] poison_obj+0x36/0x45 [] tcp_send_active_reset+0x15/0x14d [] dbg_redzone1+0x1c/0x25 [] tcp_send_active_reset+0x15/0x14d [] cache_alloc_debugcheck_after+0x189/0x1c8 [] tcp_transmit_skb+0x764/0x786 [] tcp_send_active_reset+0xf9/0x14d [] tcp_close+0x39a/0x960 [] inet_release+0x69/0x80 [] sock_release+0x4f/0xcf [] sock_close+0x2c/0x30 [] __fput+0xac/0x197 [] filp_close+0x59/0x61 [] sys_close+0x85/0xc7 [] tracesys+0xd5/0xe0 So, in brief: * a received packet for socket in TCP_CLOSE_WAIT state triggers tcp_reset() which clears inet_sk(sk)->num and put socket into TCP_CLOSE state * an attempt to write to that socket forces inet_autobind() to get a new port (but the write itself fails with -EPIPE) * tcp_close() called for socket in TCP_CLOSE state sends an active reset via socket with newly allocated port This adds an additional check in tcp_close() for already closed sockets. We do not want to send anything to closed sockets. Signed-off-by: Konstantin Khorenko Signed-off-by: David S. Miller r0…