[PATCH 06/10] af_unix: record the pid of the connecting thread

From: Christian Brauner

Date: Mon Aug 31 2026 - 07:26:27 EST


Currently only the struct pid of the thread-group leader is recorded.
The identity of the actual thread that connected to a given socket
cannot be retrieved.

Add the plumbing to make it possible to retrieve a pidfd for the
connecting thread. Nothing uses the thread-specific struct pid yet. No
functional changes.

Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
net/unix/af_unix.c | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 335abd23c9bf..d01ee76c8026 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -743,51 +743,47 @@ struct unix_peercred {

static inline int prepare_peercred(struct unix_peercred *peercred)
{
- struct pid *pid;
int err;

- pid = task_tgid(current);
- err = pidfs_register_pid(pid);
- if (likely(!err)) {
- peercred->peer_pid[PIDTYPE_TGID] = get_pid(pid);
- peercred->peer_cred = get_current_cred();
+ get_task_pids(peercred->peer_pid, current);
+ err = pidfs_register_pids(peercred->peer_pid);
+ if (unlikely(err)) {
+ put_pids(peercred->peer_pid);
+ return err;
}
- return err;
+
+ peercred->peer_cred = get_current_cred();
+ return 0;
}

static void drop_peercred(struct unix_peercred *peercred)
{
const struct cred *cred = NULL;
- struct pid *pid = NULL;

might_sleep();

- swap(peercred->peer_pid[PIDTYPE_TGID], pid);
+ put_pids(peercred->peer_pid);
swap(peercred->peer_cred, cred);
-
- put_pid(pid);
put_cred(cred);
}

static inline void init_peercred(struct sock *sk,
const struct unix_peercred *peercred)
{
- sk->sk_peer_pid[PIDTYPE_TGID] = peercred->peer_pid[PIDTYPE_TGID];
+ memcpy(sk->sk_peer_pid, peercred->peer_pid, sizeof(sk->sk_peer_pid));
sk->sk_peer_cred = peercred->peer_cred;
}

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

spin_lock(&sk->sk_peer_lock);
- old_pid = sk->sk_peer_pid[PIDTYPE_TGID];
+ swap_pids(sk->sk_peer_pid, peercred->peer_pid);
old_cred = sk->sk_peer_cred;
- init_peercred(sk, peercred);
+ sk->sk_peer_cred = peercred->peer_cred;
spin_unlock(&sk->sk_peer_lock);

- peercred->peer_pid[PIDTYPE_TGID] = old_pid;
peercred->peer_cred = old_cred;
}

@@ -796,7 +792,7 @@ static void copy_peercred(struct sock *sk, struct sock *peersk)
lockdep_assert_held(&unix_sk(peersk)->lock);

spin_lock(&sk->sk_peer_lock);
- sk->sk_peer_pid[PIDTYPE_TGID] = get_pid(peersk->sk_peer_pid[PIDTYPE_TGID]);
+ get_pids(sk->sk_peer_pid, peersk->sk_peer_pid);
sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
spin_unlock(&sk->sk_peer_lock);
}

--
2.53.0