From: Kuniyuki Iwashima Date: Wed, 2 Jul 2025 22:35:13 +0000 (+0000) Subject: af_unix: Don't hold unix_state_lock() in __unix_dgram_recvmsg(). X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b429a5ad19cb4efe63d18388a2a4deebcba742c6;p=thirdparty%2Fkernel%2Fstable.git af_unix: Don't hold unix_state_lock() in __unix_dgram_recvmsg(). When __skb_try_recv_datagram() returns NULL in __unix_dgram_recvmsg(), we hold unix_state_lock() unconditionally. This is because SOCK_SEQPACKET sk needs to return EOF in case its peer has been close()d concurrently. This behaviour totally depends on the timing of the peer's close() and reading sk->sk_shutdown, and taking the lock does not play a role. Let's drop the lock from __unix_dgram_recvmsg() and use READ_ONCE(). Signed-off-by: Kuniyuki Iwashima Reviewed-by: Willem de Bruijn Link: https://patch.msgid.link/20250702223606.1054680-2-kuniyu@google.com Signed-off-by: Jakub Kicinski --- diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index cd0d582bc7d4..becd84737635 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2527,12 +2527,10 @@ int __unix_dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t size, &err, &timeo, last)); if (!skb) { /* implies iolock unlocked */ - unix_state_lock(sk); /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN && - (sk->sk_shutdown & RCV_SHUTDOWN)) + (READ_ONCE(sk->sk_shutdown) & RCV_SHUTDOWN)) err = 0; - unix_state_unlock(sk); goto out; }