linux-stable/net/unix
Kirill Tkhai ccfdd4790b unix: Fix race in SOCK_SEQPACKET's unix_dgram_sendmsg()
[ Upstream commit 3ff8bff704 ]

There is a race resulting in alive SOCK_SEQPACKET socket
may change its state from TCP_ESTABLISHED to TCP_CLOSE:

unix_release_sock(peer)                  unix_dgram_sendmsg(sk)
  sock_orphan(peer)
    sock_set_flag(peer, SOCK_DEAD)
                                           sock_alloc_send_pskb()
                                             if !(sk->sk_shutdown & SEND_SHUTDOWN)
                                               OK
                                           if sock_flag(peer, SOCK_DEAD)
                                             sk->sk_state = TCP_CLOSE
  sk->sk_shutdown = SHUTDOWN_MASK

After that socket sk remains almost normal: it is able to connect, listen, accept
and recvmsg, while it can't sendmsg.

Since this is the only possibility for alive SOCK_SEQPACKET to change
the state in such way, we should better fix this strange and potentially
danger corner case.

Note, that we will return EPIPE here like this is normally done in sock_alloc_send_pskb().
Originally used ECONNREFUSED looks strange, since it's strange to return
a specific retval in dependence of race in kernel, when user can't affect on this.

Also, move TCP_CLOSE assignment for SOCK_DGRAM sockets under state lock
to fix race with unix_dgram_connect():

unix_dgram_connect(other)            unix_dgram_sendmsg(sk)
                                       unix_peer(sk) = NULL
                                       unix_state_unlock(sk)
  unix_state_double_lock(sk, other)
  sk->sk_state  = TCP_ESTABLISHED
  unix_peer(sk) = other
  unix_state_double_unlock(sk, other)
                                       sk->sk_state  = TCP_CLOSED

This patch fixes both of these races.

Fixes: 83301b5367 ("af_unix: Set TCP_ESTABLISHED for datagram sockets too")
Signed-off-by: Kirill Tkhai <tkhai@ya.ru>
Link: https://lore.kernel.org/r/135fda25-22d5-837a-782b-ceee50e19844@ya.ru
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2022-12-31 13:26:38 +01:00
..
Kconfig af_unix: Add OOB support 2021-08-04 09:55:52 +01:00
Makefile af_unix: Implement ->psock_update_sk_prot() 2021-07-15 18:17:50 -07:00
af_unix.c unix: Fix race in SOCK_SEQPACKET's unix_dgram_sendmsg() 2022-12-31 13:26:38 +01:00
diag.c af_unix: Get user_ns from in_skb in unix_diag_get_exact(). 2022-12-14 11:40:58 +01:00
garbage.c io_uring/af_unix: defer registered files gc to io_uring release 2022-10-21 12:37:33 +02:00
scm.c af_unix: annote lockless accesses to unix_tot_inflight & gc_in_progress 2022-01-14 18:31:37 -08:00
scm.h
sysctl_net_unix.c af_unix: fix unix_sysctl_register() error path 2022-07-09 12:27:33 +01:00
unix_bpf.c net: remove SOCK_SUPPORT_ZC from sockmap 2022-11-10 18:17:35 +01:00