]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
af_unix: Use skb_queue_empty_lockless() in unix_release_sock().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Tue, 4 Jun 2024 16:52:39 +0000 (09:52 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 6 Jun 2024 10:57:15 +0000 (12:57 +0200)
If the socket type is SOCK_STREAM or SOCK_SEQPACKET, unix_release_sock()
checks the length of the peer socket's recvq under unix_state_lock().

However, unix_stream_read_generic() calls skb_unlink() after releasing
the lock.  Also, for SOCK_SEQPACKET, __skb_try_recv_datagram() unlinks
skb without unix_state_lock().

Thues, unix_state_lock() does not protect qlen.

Let's use skb_queue_empty_lockless() in unix_release_sock().

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/unix/af_unix.c

index eb3ba3448ed34fc6ef1e9b9ff07c07e2a7389f7f..80846279de9f3b94be5c60eda8be17f2adeeaf6b 100644 (file)
@@ -631,7 +631,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
                        unix_state_lock(skpair);
                        /* No more writes */
                        WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK);
-                       if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
+                       if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || embrion)
                                WRITE_ONCE(skpair->sk_err, ECONNRESET);
                        unix_state_unlock(skpair);
                        skpair->sk_state_change(skpair);