]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
af_unix: Don't hold unix_state_lock() in __unix_dgram_recvmsg().
authorKuniyuki Iwashima <kuniyu@google.com>
Wed, 2 Jul 2025 22:35:13 +0000 (22:35 +0000)
committerJakub Kicinski <kuba@kernel.org>
Wed, 9 Jul 2025 01:05:25 +0000 (18:05 -0700)
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 <kuniyu@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20250702223606.1054680-2-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/unix/af_unix.c

index cd0d582bc7d48fbf9cd917c72e1fe4e88232916e..becd84737635cd125d5e10d28fd940b88e9ffb26 100644 (file)
@@ -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;
        }