Commit 350d4546 authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by David S. Miller
Browse files

af_unix: Factorise test_bit() for SOCK_PASSCRED and SOCK_PASSPIDFD.



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: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ea15e046
Loading
Loading
Loading
Loading
+15 −22
Original line number Diff line number Diff line
@@ -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 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
			/* 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);