summaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@amazon.com>2024-06-20 22:56:23 +0200
committerPaolo Abeni <pabeni@redhat.com>2024-06-25 11:10:19 +0200
commit22e5751b0524fedd4f345412d8d3394387471ab7 (patch)
tree1fb44e4934b36a9e237bb5da8f98fe2d61869d6f /net/unix
parentaf_unix: Remove put_pid()/put_cred() in copy_peercred(). (diff)
downloadlinux-22e5751b0524fedd4f345412d8d3394387471ab7.tar.xz
linux-22e5751b0524fedd4f345412d8d3394387471ab7.zip
af_unix: Don't use spin_lock_nested() in copy_peercred().
When (AF_UNIX, SOCK_STREAM) socket connect()s to a listening socket, the listener's sk_peer_pid/sk_peer_cred are copied to the client in copy_peercred(). Then, two sk_peer_locks are held there; one is client's and another is listener's. However, the latter is not needed because we hold the listner's unix_state_lock() there and unix_listen() cannot update the cred concurrently. Let's drop the unnecessary spin_lock() and use the bare spin_lock() for the client to protect concurrent read by getsockopt(SO_PEERCRED). Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c13
1 files changed, 3 insertions, 10 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 3d0ace7ca017..103a7909cb1a 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -772,19 +772,12 @@ static void update_peercred(struct sock *sk)
static void copy_peercred(struct sock *sk, struct sock *peersk)
{
- if (sk < peersk) {
- spin_lock(&sk->sk_peer_lock);
- spin_lock_nested(&peersk->sk_peer_lock, SINGLE_DEPTH_NESTING);
- } else {
- spin_lock(&peersk->sk_peer_lock);
- spin_lock_nested(&sk->sk_peer_lock, SINGLE_DEPTH_NESTING);
- }
+ lockdep_assert_held(&unix_sk(peersk)->lock);
- sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
+ spin_lock(&sk->sk_peer_lock);
+ sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
-
spin_unlock(&sk->sk_peer_lock);
- spin_unlock(&peersk->sk_peer_lock);
}
static int unix_listen(struct socket *sock, int backlog)