]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
af_unix: Don't acquire unix_state_lock() for sock_i_ino().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Thu, 20 Jun 2024 20:56:17 +0000 (13:56 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 25 Jun 2024 09:10:18 +0000 (11:10 +0200)
sk_diag_dump_peer() and sk_diag_dump() call unix_state_lock() for
sock_i_ino() which reads SOCK_INODE(sk->sk_socket)->i_ino, but it's
protected by sk->sk_callback_lock.

Let's remove unnecessary unix_state_lock().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/unix/diag.c

index 937edf4afed41339afce117bd08f9a58bb2a6118..d2d66727b0da586de3d3fb26cd523ad719e77cb2 100644 (file)
@@ -47,9 +47,7 @@ static int sk_diag_dump_peer(struct sock *sk, struct sk_buff *nlskb)
 
        peer = unix_peer_get(sk);
        if (peer) {
-               unix_state_lock(peer);
                ino = sock_i_ino(peer);
-               unix_state_unlock(peer);
                sock_put(peer);
 
                return nla_put_u32(nlskb, UNIX_DIAG_PEER, ino);
@@ -180,22 +178,6 @@ out_nlmsg_trim:
        return -EMSGSIZE;
 }
 
-static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
-                       struct user_namespace *user_ns,
-                       u32 portid, u32 seq, u32 flags)
-{
-       int sk_ino;
-
-       unix_state_lock(sk);
-       sk_ino = sock_i_ino(sk);
-       unix_state_unlock(sk);
-
-       if (!sk_ino)
-               return 0;
-
-       return sk_diag_fill(sk, skb, req, user_ns, portid, seq, flags, sk_ino);
-}
-
 static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct net *net = sock_net(skb->sk);
@@ -213,14 +195,22 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
                num = 0;
                spin_lock(&net->unx.table.locks[slot]);
                sk_for_each(sk, &net->unx.table.buckets[slot]) {
+                       int sk_ino;
+
                        if (num < s_num)
                                goto next;
+
                        if (!(req->udiag_states & (1 << READ_ONCE(sk->sk_state))))
                                goto next;
-                       if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk),
+
+                       sk_ino = sock_i_ino(sk);
+                       if (!sk_ino)
+                               goto next;
+
+                       if (sk_diag_fill(sk, skb, req, sk_user_ns(skb->sk),
                                         NETLINK_CB(cb->skb).portid,
                                         cb->nlh->nlmsg_seq,
-                                        NLM_F_MULTI) < 0) {
+                                        NLM_F_MULTI, sk_ino) < 0) {
                                spin_unlock(&net->unx.table.locks[slot]);
                                goto done;
                        }