diff options
author | Kuniyuki Iwashima <kuniyu@amazon.com> | 2024-06-04 19:52:39 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-06-21 15:40:09 +0300 |
commit | 13f8afd9c29400e2d9e83c69fc26fe7f36b996f5 (patch) | |
tree | c24cf40c3437aff3500fdc273d20e75dae63cd5b /net | |
parent | d42d1f981967cd78717e6f54cd6ea8e4d3239d1e (diff) | |
download | linux-13f8afd9c29400e2d9e83c69fc26fe7f36b996f5.tar.xz |
af_unix: Use skb_queue_empty_lockless() in unix_release_sock().
[ Upstream commit 83690b82d228b3570565ebd0b41873933238b97f ]
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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/unix/af_unix.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f0760afad71f..cbc011ceb89b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -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); |