summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@amazon.com>2024-06-20 13:56:21 -0700
committerPaolo Abeni <pabeni@redhat.com>2024-06-25 11:10:18 +0200
commitfaf489e6896d645a679d3d90a2d1d5d12c6b3e13 (patch)
treeaaf95bbcdcfddab81bbec0a7dbc52aa62460e9be /net
parent8647ece4814f3bfdb5f7a8e19f882c9b89299a07 (diff)
af_unix: Set sk_peer_pid/sk_peer_cred locklessly for new socket.
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>
Diffstat (limited to 'net')
-rw-r--r--net/unix/af_unix.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 89675879038d..d11664c2faad 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -751,14 +751,19 @@ 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);
@@ -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: