]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
af_unix: Factorise test_bit() for SOCK_PASSCRED and SOCK_PASSPIDFD.
authorKuniyuki Iwashima <kuniyu@amazon.com>
Mon, 19 May 2025 20:57:52 +0000 (13:57 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 23 May 2025 09:24:18 +0000 (10:24 +0100)
Currently, the same checks for SOCK_PASSCRED and SOCK_PASSPIDFD
are scattered across many places.

Let's centralise the bit tests to make the following changes cleaner.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/unix/af_unix.c

index 2ab20821d6bb244a09e0364e1c649042360e23b1..464e183ffdb83314c04ecd05b4abd86071518273 100644 (file)
@@ -765,6 +765,14 @@ static void copy_peercred(struct sock *sk, struct sock *peersk)
        spin_unlock(&sk->sk_peer_lock);
 }
 
+static bool unix_may_passcred(const struct sock *sk)
+{
+       struct socket *sock = sk->sk_socket;
+
+       return test_bit(SOCK_PASSCRED, &sock->flags) ||
+               test_bit(SOCK_PASSPIDFD, &sock->flags);
+}
+
 static int unix_listen(struct socket *sock, int backlog)
 {
        int err;
@@ -1411,9 +1419,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
                if (err)
                        goto out;
 
-               if ((test_bit(SOCK_PASSCRED, &sock->flags) ||
-                    test_bit(SOCK_PASSPIDFD, &sock->flags)) &&
-                   !READ_ONCE(unix_sk(sk)->addr)) {
+               if (unix_may_passcred(sk) && !READ_ONCE(unix_sk(sk)->addr)) {
                        err = unix_autobind(sk);
                        if (err)
                                goto out;
@@ -1531,9 +1537,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
        if (err)
                goto out;
 
-       if ((test_bit(SOCK_PASSCRED, &sock->flags) ||
-            test_bit(SOCK_PASSPIDFD, &sock->flags)) &&
-           !READ_ONCE(u->addr)) {
+       if (unix_may_passcred(sk) && !READ_ONCE(u->addr)) {
                err = unix_autobind(sk);
                if (err)
                        goto out;
@@ -1877,16 +1881,6 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
        return err;
 }
 
-static bool unix_passcred_enabled(const struct socket *sock,
-                                 const struct sock *other)
-{
-       return test_bit(SOCK_PASSCRED, &sock->flags) ||
-              test_bit(SOCK_PASSPIDFD, &sock->flags) ||
-              !other->sk_socket ||
-              test_bit(SOCK_PASSCRED, &other->sk_socket->flags) ||
-              test_bit(SOCK_PASSPIDFD, &other->sk_socket->flags);
-}
-
 /*
  * Some apps rely on write() giving SCM_CREDENTIALS
  * We include credentials if source or destination socket
@@ -1897,7 +1891,9 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
 {
        if (UNIXCB(skb).pid)
                return;
-       if (unix_passcred_enabled(sock, other)) {
+
+       if (unix_may_passcred(sock->sk) ||
+           !other->sk_socket || unix_may_passcred(other)) {
                UNIXCB(skb).pid  = get_pid(task_tgid(current));
                current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
        }
@@ -1974,9 +1970,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
                        goto out;
        }
 
-       if ((test_bit(SOCK_PASSCRED, &sock->flags) ||
-            test_bit(SOCK_PASSPIDFD, &sock->flags)) &&
-           !READ_ONCE(u->addr)) {
+       if (unix_may_passcred(sk) && !READ_ONCE(u->addr)) {
                err = unix_autobind(sk);
                if (err)
                        goto out;
@@ -2846,8 +2840,7 @@ unlock:
                        /* Never glue messages from different writers */
                        if (!unix_skb_scm_eq(skb, &scm))
                                break;
-               } else if (test_bit(SOCK_PASSCRED, &sock->flags) ||
-                          test_bit(SOCK_PASSPIDFD, &sock->flags)) {
+               } else if (unix_may_passcred(sk)) {
                        /* Copy credentials */
                        scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
                        unix_set_secdata(&scm, skb);