Skip to content

Commit

Permalink
af_unix: Set sk_peer_pid/sk_peer_cred locklessly for new socket.
Browse files Browse the repository at this point in the history
init_peercred() is called in 3 places:

  1. socketpair() : both sockets
  2. connect()    : child socket
  3. listen()     : listening socket

The first two need not hold sk_peer_lock because no one can
touch the socket.

Let's set cred/pid without holding lock for the two cases and
rename the old init_peercred() to update_peercred() to properly
reflect the use case.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
q2ven authored and Paolo Abeni committed Jun 25, 2024
1 parent 8647ece commit faf489e
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions net/unix/af_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -750,15 +750,20 @@ static void unix_release_sock(struct sock *sk, int embrion)
}

static void init_peercred(struct sock *sk)
{
sk->sk_peer_pid = get_pid(task_tgid(current));
sk->sk_peer_cred = get_current_cred();
}

static void update_peercred(struct sock *sk)
{
const struct cred *old_cred;
struct pid *old_pid;

spin_lock(&sk->sk_peer_lock);
old_pid = sk->sk_peer_pid;
old_cred = sk->sk_peer_cred;
sk->sk_peer_pid = get_pid(task_tgid(current));
sk->sk_peer_cred = get_current_cred();
init_peercred(sk);
spin_unlock(&sk->sk_peer_lock);

put_pid(old_pid);
Expand Down Expand Up @@ -810,7 +815,7 @@ static int unix_listen(struct socket *sock, int backlog)
WRITE_ONCE(sk->sk_state, TCP_LISTEN);

/* set credentials so connect can copy them */
init_peercred(sk);
update_peercred(sk);
err = 0;

out_unlock:
Expand Down

0 comments on commit faf489e

Please sign in to comment.