]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
af_unix: Clean up SOCK_DEAD error paths in unix_dgram_sendmsg().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Fri, 13 Dec 2024 11:08:48 +0000 (20:08 +0900)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 17 Dec 2024 11:08:28 +0000 (12:08 +0100)
When other has SOCK_DEAD in unix_dgram_sendmsg(), we hold
unix_state_lock() for the sender socket first.

However, we do not need it for sk->sk_type.

Let's move the lock down a bit.

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

index b8adfb41d11bcdfdb39cbe4979170a02960ff8e3..22c689b0044fc7cd4961ac6bfa5e49b4802968f7 100644 (file)
@@ -2070,23 +2070,23 @@ restart_locked:
        }
 
        if (unlikely(sock_flag(other, SOCK_DEAD))) {
-               /*
-                *      Check with 1003.1g - what should
-                *      datagram error
-                */
-               unix_state_unlock(other);
+               /* Check with 1003.1g - what should datagram error */
 
-               if (!sk_locked)
-                       unix_state_lock(sk);
+               unix_state_unlock(other);
 
                if (sk->sk_type == SOCK_SEQPACKET) {
                        /* We are here only when racing with unix_release_sock()
                         * is clearing @other. Never change state to TCP_CLOSE
                         * unlike SOCK_DGRAM wants.
                         */
-                       unix_state_unlock(sk);
                        err = -EPIPE;
-               } else if (unix_peer(sk) == other) {
+                       goto out_free;
+               }
+
+               if (!sk_locked)
+                       unix_state_lock(sk);
+
+               if (unix_peer(sk) == other) {
                        unix_peer(sk) = NULL;
                        unix_dgram_peer_wake_disconnect_wakeup(sk, other);
 
@@ -2096,15 +2096,15 @@ restart_locked:
                        unix_dgram_disconnected(sk, other);
                        sock_put(other);
                        err = -ECONNREFUSED;
-               } else {
-                       unix_state_unlock(sk);
-
-                       if (!msg->msg_namelen)
-                               err = -ECONNRESET;
+                       goto out_free;
                }
 
-               if (err)
+               unix_state_unlock(sk);
+
+               if (!msg->msg_namelen) {
+                       err = -ECONNRESET;
                        goto out_free;
+               }
 
                goto lookup;
        }